mpremote cp fails with apostrophe in destination filename
Port, board and/or hardware
Any platform (Windows, Linux, macOS) - affects mpremote tool when copying files with apostrophe (') in the filename.
MicroPython version
- mpremote 1.27.0
- Tested against MicroPython unix port and ESP32
The issue is in mpremote itself, not in MicroPython firmware.
Reproduction
-
Create a test file with an apostrophe in the name:
mkdir unicode_test echo "test" > "unicode_test\O'zbek_Ismoilov.txt" -
Attempt to copy to MicroPython device with the same destination name:
mpremote cp "unicode_test\O'zbek_Ismoilov.txt" ":/O'zbek_Ismoilov.txt" -
Observe the error.
Expected behaviour
mpremote cp should successfully copy files with apostrophes in filenames. The apostrophe should be properly escaped when constructing Python commands to send to the MicroPython REPL.
Observed behaviour
The command fails with a SyntaxError because the apostrophe breaks the Python string literal sent to the REPL.
PS D:\mypython\unicode_mpy> mpremote cp "unicode_test\O'zbek_Ismoilov.txt" ":/O'zbek_Ismoilov.txt"
cp unicode_test\O'zbek_Ismoilov.txt :/O'zbek_Ismoilov.txt
mpremote: Error with transport:
Traceback (most recent call last):
File "<stdin>", line 1
SyntaxError: invalid syntax
Additional Information
mpremote sends filenames to MicroPython's REPL as Python string literals using single quotes. When a filename contains an apostrophe ', it prematurely closes the string:
# What mpremote probably sends:
open('/O'zbek_Ismoilov.txt', 'wb')
# ^ This closes the string prematurely!
# Result is invalid Python syntax
Affected Characters
Any filename containing:
- Single quote / apostrophe:
'(U+0027) - Possibly other quote-like characters that need escaping
Suggested Fix
Properly escape quotes when constructing Python commands to send to the REPL:
Option A: Escape single quotes
# Instead of:
cmd = f"open('{filename}', 'wb')"
# Use:
escaped_filename = filename.replace("\\", "\\\\").replace("'", "\\'")
cmd = f"open('{escaped_filename}', 'wb')"
Option B: Use double quotes for filenames
cmd = f'open("{filename}", "wb")'
# Note: would then need to escape double quotes in filenames
Option C: Use repr() for proper escaping
cmd = f"open({repr(filename)}, 'wb')"
Found via : https://github.com/Josverl/unicode_mpy
Code of Conduct
Yes, I agree
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