mpremote cp fails with equals sign (=) in filename
Port, board and/or hardware
Any platform (Windows, Linux, macOS) - affects mpremote tool when copying files with equals sign (=) in the filename.
MicroPython version
- mpremote 1.27.0
- Tested against MicroPython unix port and ESP32
The issue is in mpremote's argument parser, not in MicroPython firmware.
Reproduction
-
Create a test file with an equals sign in the name:
mkdir unicode_test echo "test" > "unicode_test\H2O_E=mc2.txt" -
Attempt to copy to MicroPython device:
mpremote cp "unicode_test\H2O_E=mc2.txt" ":/test.txt" -
Observe the error.
Expected behaviour
mpremote cp should successfully copy files with equals signs in filenames. The argument parser should not interpret = within filenames as key-value separators.
Filenames with = are valid on all major operating systems (Windows, Linux, macOS) and should be supported.
Observed behaviour
The command fails because mpremote's argument parser interprets the = character as a key-value separator, truncating the filename:
- Input:
H₂O_E=mc².txt - Parsed as: key=
H₂O_E, value=mc².txt - Error: "unexpected argument" because the truncated filename doesn't match expected syntax
Additional Information
mpremote's argument parser (likely in main.py or the command dispatch logic) splits arguments on = to support key-value style arguments. This incorrectly affects filenames that legitimately contain the = character.
Affected Filenames
Any filename containing:
- Equals sign:
=(U+003D)
Common examples:
E=mc².txta=b.logkey=value.jsonbase64==data.bin
Suggested Fix
Modify the argument parser to not split on = within file path arguments. Options include:
- Stop splitting on
=for positional arguments - Only use=splitting for named/keyword arguments - Check if the argument is a valid file path first - If the argument exists as a file, don't split it
- Require
--key=valuesyntax - Only split on=when preceded by--
Code of Conduct
Yes, I agree
tools/mpremote: Fix "fs cp -r" on Windows.
Currently when using mpremote fs cp -r _manifest : on windows, it does not correctly handle the \ path separator, resulting in things like
cp _manifest\config_def.mpy :_manifest/_manifest\art.mpy
which gets even worse on-device:
os.listdir("/_manifest")
['_manifest\x07rt.mpy', ...]
Changing to a simply '/',join() appears to fix this problem cleanly.