mpytool 2.2.3__tar.gz → 2.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {mpytool-2.2.3 → mpytool-2.3.0}/PKG-INFO +175 -13
- {mpytool-2.2.3 → mpytool-2.3.0}/README.md +174 -12
- {mpytool-2.2.3 → mpytool-2.3.0}/mpytool/__init__.py +1 -1
- mpytool-2.3.0/mpytool/cmd_cp.py +847 -0
- {mpytool-2.2.3 → mpytool-2.3.0}/mpytool/conn.py +99 -13
- {mpytool-2.2.3 → mpytool-2.3.0}/mpytool/conn_serial.py +6 -1
- {mpytool-2.2.3 → mpytool-2.3.0}/mpytool/conn_socket.py +14 -1
- {mpytool-2.2.3 → mpytool-2.3.0}/mpytool/logger.py +11 -4
- mpytool-2.3.0/mpytool/mount.py +1053 -0
- {mpytool-2.2.3 → mpytool-2.3.0}/mpytool/mpy.py +321 -37
- {mpytool-2.2.3 → mpytool-2.3.0}/mpytool/mpy_comm.py +111 -56
- mpytool-2.3.0/mpytool/mpy_cross.py +173 -0
- mpytool-2.3.0/mpytool/mpytool.py +1518 -0
- {mpytool-2.2.3 → mpytool-2.3.0}/mpytool/terminal.py +6 -6
- {mpytool-2.2.3 → mpytool-2.3.0}/mpytool/terminal_unix.py +0 -2
- {mpytool-2.2.3 → mpytool-2.3.0}/mpytool/utils.py +6 -7
- {mpytool-2.2.3 → mpytool-2.3.0}/mpytool.egg-info/PKG-INFO +175 -13
- {mpytool-2.2.3 → mpytool-2.3.0}/mpytool.egg-info/SOURCES.txt +5 -0
- {mpytool-2.2.3 → mpytool-2.3.0}/pyproject.toml +1 -1
- mpytool-2.2.3/tests/test_mpytool.py → mpytool-2.3.0/tests/test_cmd_cp.py +373 -498
- {mpytool-2.2.3 → mpytool-2.3.0}/tests/test_integration.py +1189 -7
- mpytool-2.3.0/tests/test_mount.py +2062 -0
- {mpytool-2.2.3 → mpytool-2.3.0}/tests/test_mpy.py +86 -30
- mpytool-2.3.0/tests/test_mpytool.py +964 -0
- mpytool-2.2.3/mpytool/mpytool.py +0 -1601
- {mpytool-2.2.3 → mpytool-2.3.0}/LICENSE +0 -0
- {mpytool-2.2.3 → mpytool-2.3.0}/mpytool/speedtest.py +0 -0
- {mpytool-2.2.3 → mpytool-2.3.0}/mpytool/terminal_win.py +0 -0
- {mpytool-2.2.3 → mpytool-2.3.0}/mpytool.egg-info/dependency_links.txt +0 -0
- {mpytool-2.2.3 → mpytool-2.3.0}/mpytool.egg-info/entry_points.txt +0 -0
- {mpytool-2.2.3 → mpytool-2.3.0}/mpytool.egg-info/requires.txt +0 -0
- {mpytool-2.2.3 → mpytool-2.3.0}/mpytool.egg-info/top_level.txt +0 -0
- {mpytool-2.2.3 → mpytool-2.3.0}/setup.cfg +0 -0
- {mpytool-2.2.3 → mpytool-2.3.0}/tests/test_errors.py +0 -0
- {mpytool-2.2.3 → mpytool-2.3.0}/tests/test_utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mpytool
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.3.0
|
|
4
4
|
Summary: MPY tool - manage files on devices running MicroPython
|
|
5
5
|
Author-email: Pavel Revak <pavel.revak@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -20,17 +20,31 @@ It is an alternative to the official [mpremote](https://docs.micropython.org/en/
|
|
|
20
20
|
|
|
21
21
|
## Features
|
|
22
22
|
|
|
23
|
-
- **Fast file transfers** - optimized chunked transfer with
|
|
24
|
-
|
|
25
|
-
- **
|
|
26
|
-
-
|
|
27
|
-
- **
|
|
28
|
-
|
|
23
|
+
- **Fast file transfers** - optimized chunked transfer with
|
|
24
|
+
automatic compression
|
|
25
|
+
- **Skip unchanged files** - compares size + SHA256 hash,
|
|
26
|
+
re-upload in <1s
|
|
27
|
+
- **Auto-detect serial port** - no need to specify `-p` when only
|
|
28
|
+
one device connected
|
|
29
|
+
- **Robust REPL handling** - works reliably with USB-UART bridges
|
|
30
|
+
(CP2102, CH340)
|
|
31
|
+
- **Multiple reset options** - soft, MCU, hardware (RTS),
|
|
32
|
+
bootloader entry
|
|
33
|
+
- **General-purpose serial terminal** - `repl` and `monitor` work
|
|
34
|
+
with any serial device
|
|
35
|
+
- **Mount local directory** - VFS mount (read-only or read-write)
|
|
36
|
+
for development without uploading to flash, with transparent
|
|
37
|
+
`.mpy` compilation and auto-remount after soft reset
|
|
38
|
+
- **Virtual submounts** - `ln` links files/directories into
|
|
39
|
+
mounted VFS (PC-side only, no device changes)
|
|
29
40
|
- **Python API** - suitable for IDE integration and automation
|
|
30
|
-
- **Raw-paste mode** - flow-controlled code execution with reduced
|
|
41
|
+
- **Raw-paste mode** - flow-controlled code execution with reduced
|
|
42
|
+
RAM usage (API)
|
|
31
43
|
- **Shell completion** - ZSH and Bash with remote path completion
|
|
32
44
|
- **Network support** - connect over TCP
|
|
33
45
|
|
|
46
|
+
See [README_mpremote.md](README_mpremote.md) for detailed comparison with mpremote.
|
|
47
|
+
|
|
34
48
|
## Installation
|
|
35
49
|
|
|
36
50
|
```
|
|
@@ -103,6 +117,7 @@ $ mpytool cp :/main.py ./ # download file to current directory
|
|
|
103
117
|
$ mpytool cp :/ ./backup/ # download entire device to backup/
|
|
104
118
|
$ mpytool cp :/old.py :/new.py # copy file on device
|
|
105
119
|
$ mpytool cp -f main.py :/ # force upload even if unchanged
|
|
120
|
+
$ mpytool cp -m myapp :/ # compile .py to .mpy via mpy-cross
|
|
106
121
|
```
|
|
107
122
|
|
|
108
123
|
Path semantics: `:` = device CWD, `:/` = device root. Trailing `/` on source = copy contents only.
|
|
@@ -114,11 +129,20 @@ Use `-f` or `--force` to upload all files regardless.
|
|
|
114
129
|
$ mpytool cp -z main.py :/ # force compression (auto-detected by default)
|
|
115
130
|
$ mpytool cp --no-compress data.bin :/ # disable compression
|
|
116
131
|
$ mpytool -c 8K cp main.py :/ # set chunk size (512, 1K, 2K, 4K, 8K, 16K, 32K)
|
|
132
|
+
$ mpytool cp -m myapp :/ # compile .py to .mpy before upload
|
|
133
|
+
$ mpytool cp -fm myapp :/ # force upload + compile .mpy
|
|
117
134
|
```
|
|
118
135
|
|
|
119
136
|
Compression is auto-detected based on device RAM and deflate module availability.
|
|
120
137
|
Chunk size is auto-detected based on free RAM (larger chunks = faster transfer).
|
|
121
138
|
|
|
139
|
+
The `-m`/`--mpy` flag compiles `.py` files to `.mpy` bytecode using `mpy-cross` before upload.
|
|
140
|
+
Compiled files are cached in `__pycache__/` (recompiled only when source changes).
|
|
141
|
+
`boot.py` and `main.py` are always uploaded as `.py` (firmware requirement).
|
|
142
|
+
Requires `mpy-cross` in PATH (`pip install mpy-cross`). If mpy-cross version differs
|
|
143
|
+
from device, automatically uses `-b` flag to target the correct bytecode version.
|
|
144
|
+
If `mpy-cross` is not found, falls back to uploading `.py` with a warning.
|
|
145
|
+
|
|
122
146
|
### Move/rename on device
|
|
123
147
|
```
|
|
124
148
|
$ mpytool mv :/old.py :/new.py # rename file
|
|
@@ -153,8 +177,24 @@ $ mpytool cd :.. # change to parent directory
|
|
|
153
177
|
$ mpytool cd :/lib -- ls # change directory and list files
|
|
154
178
|
```
|
|
155
179
|
|
|
156
|
-
###
|
|
180
|
+
### Module search path (sys.path)
|
|
181
|
+
```
|
|
182
|
+
$ mpytool path # show current sys.path
|
|
183
|
+
'', '/lib'
|
|
184
|
+
$ mpytool path : :/lib # replace entire sys.path
|
|
185
|
+
$ mpytool path -f :/custom # prepend to sys.path (remove duplicates)
|
|
186
|
+
$ mpytool path -a :/sdcard/lib # append to sys.path (remove duplicates)
|
|
187
|
+
$ mpytool path -d :/custom # delete from sys.path
|
|
188
|
+
$ mpytool path -f : :/lib :/extra # prepend multiple paths
|
|
189
|
+
$ mpytool cd :/app -- path -f : # combine with cd to set working dir
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
Path semantics: `:` = empty string (CWD) in sys.path, `:/` = root directory. The `-f` and `-a` flags automatically remove duplicates (move existing paths to new position).
|
|
193
|
+
|
|
194
|
+
### Stop, reset and REPL
|
|
157
195
|
```
|
|
196
|
+
$ mpytool stop # stop running program (Ctrl-C)
|
|
197
|
+
$ mpytool stop -- repl # stop and enter REPL
|
|
158
198
|
$ mpytool reset # soft reset (Ctrl-D, runs boot.py/main.py)
|
|
159
199
|
$ mpytool reset --raw # soft reset in raw REPL (clears RAM only)
|
|
160
200
|
$ mpytool reset --machine # MCU reset (machine.reset, auto-reconnect)
|
|
@@ -170,11 +210,18 @@ $ mpytool sleep 2 # sleep for 2 seconds (useful between commands)
|
|
|
170
210
|
### Serial terminal and monitor (general purpose)
|
|
171
211
|
```
|
|
172
212
|
$ mpytool repl # auto-detect port, 115200 baud
|
|
213
|
+
REPL (Ctrl+] to exit)
|
|
214
|
+
|
|
215
|
+
$ mpytool -v repl # verbose: shows CWD and sys.path before REPL
|
|
216
|
+
REPL (Ctrl+] to exit) CWD: / PATH: : :.frozen :/lib
|
|
217
|
+
|
|
173
218
|
$ mpytool -p /dev/ttyUSB0 repl # specify port
|
|
174
219
|
$ mpytool -b 9600 repl # specify baudrate
|
|
175
220
|
$ mpytool -p /dev/ttyUSB0 -b 9600 monitor # monitor at 9600 baud
|
|
176
221
|
```
|
|
177
222
|
|
|
223
|
+
The `repl` command with `-v` flag displays current working directory (CWD) and `sys.path` before entering REPL, making it easy to see the device state after `mount`, `cd`, or `path` commands.
|
|
224
|
+
|
|
178
225
|
Both `repl` and `monitor` can be used as general-purpose serial tools - not just for MicroPython devices. Use them to interact with any serial device (Arduino, ESP with custom firmware, GPS modules, etc.). When only one serial port is detected, it is used automatically. Default baudrate is 115200.
|
|
179
226
|
|
|
180
227
|
### Execute Python code on device
|
|
@@ -189,6 +236,121 @@ $ mpytool run script.py # run script (fire-and-forget)
|
|
|
189
236
|
$ mpytool run script.py -- monitor # run script and capture output
|
|
190
237
|
```
|
|
191
238
|
|
|
239
|
+
### Edit file on device
|
|
240
|
+
```
|
|
241
|
+
$ mpytool edit :boot.py # edit file (uses $VISUAL or $EDITOR)
|
|
242
|
+
$ mpytool edit :/lib/config.py # absolute path
|
|
243
|
+
$ mpytool edit --editor vim :main.py # explicit editor
|
|
244
|
+
$ mpytool edit :newfile.py # create new file if doesn't exist
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
Downloads file to a temp file, opens in editor, uploads back if changed.
|
|
248
|
+
Editor priority: `--editor` > `$VISUAL` > `$EDITOR` > error.
|
|
249
|
+
|
|
250
|
+
### Device RTC (real-time clock)
|
|
251
|
+
```
|
|
252
|
+
$ mpytool rtc # display current RTC
|
|
253
|
+
2026-02-21 15:30:45
|
|
254
|
+
|
|
255
|
+
$ mpytool rtc --set # set RTC to local PC time
|
|
256
|
+
RTC set to 2026-02-21 15:30:45 (local)
|
|
257
|
+
|
|
258
|
+
$ mpytool rtc --utc # set RTC to UTC time
|
|
259
|
+
RTC set to 2026-02-21 14:30:45 (UTC)
|
|
260
|
+
|
|
261
|
+
$ mpytool rtc "2026-02-21 14:30:00" # set RTC to specific datetime
|
|
262
|
+
RTC set to 2026-02-21 14:30:00
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
Flags: `-s`/`--set` and `-l`/`--local` both set local time, `-u`/`--utc` sets UTC.
|
|
266
|
+
Manual datetime format: `YYYY-MM-DD HH:MM:SS`.
|
|
267
|
+
|
|
268
|
+
### Mount local directory on device
|
|
269
|
+
```
|
|
270
|
+
$ mpytool mount ./src # mount ./src as /remote, auto-start REPL
|
|
271
|
+
Mounted ./src on /remote (readonly)
|
|
272
|
+
Changed CWD to /remote
|
|
273
|
+
REPL (Ctrl+] to exit)
|
|
274
|
+
|
|
275
|
+
$ mpytool -v mount ./src :/app # mount as /app instead of /remote (verbose)
|
|
276
|
+
Mounted ./src on /app (readonly)
|
|
277
|
+
Changed CWD to /app
|
|
278
|
+
REPL (Ctrl+] to exit) CWD: /app PATH: : :.frozen :/lib
|
|
279
|
+
|
|
280
|
+
$ mpytool mount -m ./src :/app # mount with automatic .mpy compilation
|
|
281
|
+
Mounted ./src on /app (readonly, .mpy compilation)
|
|
282
|
+
Changed CWD to /app
|
|
283
|
+
>>> import foo # imports /app/foo.mpy (compiled from ./src/foo.py)
|
|
284
|
+
|
|
285
|
+
$ mpytool mount -w ./workspace :/work # mount as read-write (can create/modify/delete files)
|
|
286
|
+
Mounted ./workspace on /work (read-write)
|
|
287
|
+
Changed CWD to /work
|
|
288
|
+
>>> f = open('/work/test.txt', 'w'); f.write('hello'); f.close() # creates local file
|
|
289
|
+
>>> import os; os.mkdir('/work/newdir') # creates local directory
|
|
290
|
+
|
|
291
|
+
$ mpytool mount ./src -- exec "import main" # mount and run code
|
|
292
|
+
$ mpytool mount ./src -- monitor # mount and monitor output
|
|
293
|
+
$ mpytool mount ./app :/app -- mount ./lib :/lib -- repl # multiple mounts (CWD = /app)
|
|
294
|
+
Mounted ./app on /app (readonly)
|
|
295
|
+
Changed CWD to /app
|
|
296
|
+
Mounted ./lib on /lib (readonly)
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
Mounts a local directory on the device as a VFS. The device can read,
|
|
300
|
+
import and execute files from the local directory without uploading
|
|
301
|
+
them to flash. Changes to local files are immediately visible on
|
|
302
|
+
the device.
|
|
303
|
+
|
|
304
|
+
**Memory overhead:** The VFS agent uses ~4.2KB of RAM on the device
|
|
305
|
+
(154 lines of MicroPython code injected during mount).
|
|
306
|
+
|
|
307
|
+
**By default, mounts are read-only.** Use `-w` / `--writable` flag
|
|
308
|
+
to enable write support — the device can create, modify and delete
|
|
309
|
+
files in the mounted directory. All changes are written directly to
|
|
310
|
+
the local filesystem.
|
|
311
|
+
|
|
312
|
+
**`-m` / `--mpy` flag:** Enables transparent `.mpy` compilation.
|
|
313
|
+
When the device imports a module, the `.py` file is automatically
|
|
314
|
+
compiled to `.mpy` bytecode on-demand and served from cache
|
|
315
|
+
(`__pycache__/`). Benefits: faster imports, less RAM usage, support
|
|
316
|
+
for `@native`/`@viper` code with `-march`. Boot files (`boot.py`,
|
|
317
|
+
`main.py`) and empty files remain as `.py`. If compilation fails,
|
|
318
|
+
automatically falls back to `.py`. Prebuilt `.mpy` files have
|
|
319
|
+
priority over cache.
|
|
320
|
+
|
|
321
|
+
The first mount automatically changes CWD to the mount point (mpremote
|
|
322
|
+
compatibility). Subsequent mounts do not change CWD. Use `cd` command
|
|
323
|
+
to change working directory manually if needed. Multiple independent
|
|
324
|
+
(non-nested) mounts are supported.
|
|
325
|
+
|
|
326
|
+
After mount, mpytool automatically enters REPL (unless `monitor` or
|
|
327
|
+
`repl` follows). In REPL you can import modules from the mounted
|
|
328
|
+
directory, Ctrl+D triggers soft reset with automatic re-mount and CWD
|
|
329
|
+
restoration to the mount point.
|
|
330
|
+
|
|
331
|
+
**Best for:** Development, testing, prototyping, debugging. For bulk
|
|
332
|
+
file transfers (uploading/downloading many files), use `cp` command
|
|
333
|
+
instead — it's optimized for throughput.
|
|
334
|
+
|
|
335
|
+
**Security:** Paths are validated to prevent traversal outside mount
|
|
336
|
+
root. Symlinks are followed and checked. Write operations require
|
|
337
|
+
explicit `-w` flag.
|
|
338
|
+
|
|
339
|
+
See [Mount VFS Comparison](README_mpremote.md#mount-vfs-comparison) for detailed comparison with mpremote.
|
|
340
|
+
|
|
341
|
+
### Link files into mounted VFS
|
|
342
|
+
```
|
|
343
|
+
$ mpytool mount ./app :/ -- ln ./drivers :/lib/ -- repl # mount app, link drivers into /lib/
|
|
344
|
+
$ mpytool mount ./app :/ -- ln ./extra.py :/lib/ -- repl # link single file into /lib/
|
|
345
|
+
$ mpytool mount ./app :/ -- ln ./pkg :/lib/pkg -- repl # link as specific name
|
|
346
|
+
$ mpytool mount ./app :/ -- ln ./pkg/ :/lib/ -- repl # link package contents into /lib/
|
|
347
|
+
$ mpytool mount ./app :/ -- ln ./a.py ./b.py :/lib/ -- repl # link multiple sources
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
Links local files or directories into an already mounted VFS as virtual submounts. Works entirely on the PC side — no changes needed on the device. Useful for composing a virtual filesystem from multiple local directories without copying.
|
|
351
|
+
|
|
352
|
+
Path semantics follow the same trailing `/` rules as `cp`: `ln dir :/lib/` creates `:/lib/dir/...`, `ln dir/ :/lib/` copies contents into `:/lib/...`. Destination must be an absolute device path with `:` prefix.
|
|
353
|
+
|
|
192
354
|
### Serial link speed test
|
|
193
355
|
```
|
|
194
356
|
$ mpytool speedtest
|
|
@@ -248,9 +410,9 @@ $ mpytool flash erase vfs --full # full erase partition
|
|
|
248
410
|
|
|
249
411
|
### OTA firmware update (ESP32)
|
|
250
412
|
```
|
|
251
|
-
$ mpytool ota firmware.app-bin # flash to next OTA partition
|
|
252
|
-
$ mpytool ota firmware.app-bin -- reset --machine # flash and reboot
|
|
253
|
-
$ mpytool ota firmware.app-bin -- reset --machine -t 30 # flash and reboot with 30s timeout
|
|
413
|
+
$ mpytool flash ota firmware.app-bin # flash to next OTA partition
|
|
414
|
+
$ mpytool flash ota firmware.app-bin -- reset --machine # flash and reboot
|
|
415
|
+
$ mpytool flash ota firmware.app-bin -- reset --machine -t 30 # flash and reboot with 30s timeout
|
|
254
416
|
```
|
|
255
417
|
|
|
256
418
|
### Multiple commands separated by `--`
|
|
@@ -378,7 +540,7 @@ For reporting bugs, please include `-ddd` output in the issue.
|
|
|
378
540
|
|
|
379
541
|
## Performance
|
|
380
542
|
|
|
381
|
-
`mpytool` uses optimized chunked transfer with automatic compression, which allows copying files very quickly. See [
|
|
543
|
+
`mpytool` uses optimized chunked transfer with automatic compression, which allows copying files very quickly. See [README_bench.md](README_bench.md) for detailed benchmarks.
|
|
382
544
|
|
|
383
545
|
### Summary
|
|
384
546
|
|
|
@@ -6,17 +6,31 @@ It is an alternative to the official [mpremote](https://docs.micropython.org/en/
|
|
|
6
6
|
|
|
7
7
|
## Features
|
|
8
8
|
|
|
9
|
-
- **Fast file transfers** - optimized chunked transfer with
|
|
10
|
-
|
|
11
|
-
- **
|
|
12
|
-
-
|
|
13
|
-
- **
|
|
14
|
-
|
|
9
|
+
- **Fast file transfers** - optimized chunked transfer with
|
|
10
|
+
automatic compression
|
|
11
|
+
- **Skip unchanged files** - compares size + SHA256 hash,
|
|
12
|
+
re-upload in <1s
|
|
13
|
+
- **Auto-detect serial port** - no need to specify `-p` when only
|
|
14
|
+
one device connected
|
|
15
|
+
- **Robust REPL handling** - works reliably with USB-UART bridges
|
|
16
|
+
(CP2102, CH340)
|
|
17
|
+
- **Multiple reset options** - soft, MCU, hardware (RTS),
|
|
18
|
+
bootloader entry
|
|
19
|
+
- **General-purpose serial terminal** - `repl` and `monitor` work
|
|
20
|
+
with any serial device
|
|
21
|
+
- **Mount local directory** - VFS mount (read-only or read-write)
|
|
22
|
+
for development without uploading to flash, with transparent
|
|
23
|
+
`.mpy` compilation and auto-remount after soft reset
|
|
24
|
+
- **Virtual submounts** - `ln` links files/directories into
|
|
25
|
+
mounted VFS (PC-side only, no device changes)
|
|
15
26
|
- **Python API** - suitable for IDE integration and automation
|
|
16
|
-
- **Raw-paste mode** - flow-controlled code execution with reduced
|
|
27
|
+
- **Raw-paste mode** - flow-controlled code execution with reduced
|
|
28
|
+
RAM usage (API)
|
|
17
29
|
- **Shell completion** - ZSH and Bash with remote path completion
|
|
18
30
|
- **Network support** - connect over TCP
|
|
19
31
|
|
|
32
|
+
See [README_mpremote.md](README_mpremote.md) for detailed comparison with mpremote.
|
|
33
|
+
|
|
20
34
|
## Installation
|
|
21
35
|
|
|
22
36
|
```
|
|
@@ -89,6 +103,7 @@ $ mpytool cp :/main.py ./ # download file to current directory
|
|
|
89
103
|
$ mpytool cp :/ ./backup/ # download entire device to backup/
|
|
90
104
|
$ mpytool cp :/old.py :/new.py # copy file on device
|
|
91
105
|
$ mpytool cp -f main.py :/ # force upload even if unchanged
|
|
106
|
+
$ mpytool cp -m myapp :/ # compile .py to .mpy via mpy-cross
|
|
92
107
|
```
|
|
93
108
|
|
|
94
109
|
Path semantics: `:` = device CWD, `:/` = device root. Trailing `/` on source = copy contents only.
|
|
@@ -100,11 +115,20 @@ Use `-f` or `--force` to upload all files regardless.
|
|
|
100
115
|
$ mpytool cp -z main.py :/ # force compression (auto-detected by default)
|
|
101
116
|
$ mpytool cp --no-compress data.bin :/ # disable compression
|
|
102
117
|
$ mpytool -c 8K cp main.py :/ # set chunk size (512, 1K, 2K, 4K, 8K, 16K, 32K)
|
|
118
|
+
$ mpytool cp -m myapp :/ # compile .py to .mpy before upload
|
|
119
|
+
$ mpytool cp -fm myapp :/ # force upload + compile .mpy
|
|
103
120
|
```
|
|
104
121
|
|
|
105
122
|
Compression is auto-detected based on device RAM and deflate module availability.
|
|
106
123
|
Chunk size is auto-detected based on free RAM (larger chunks = faster transfer).
|
|
107
124
|
|
|
125
|
+
The `-m`/`--mpy` flag compiles `.py` files to `.mpy` bytecode using `mpy-cross` before upload.
|
|
126
|
+
Compiled files are cached in `__pycache__/` (recompiled only when source changes).
|
|
127
|
+
`boot.py` and `main.py` are always uploaded as `.py` (firmware requirement).
|
|
128
|
+
Requires `mpy-cross` in PATH (`pip install mpy-cross`). If mpy-cross version differs
|
|
129
|
+
from device, automatically uses `-b` flag to target the correct bytecode version.
|
|
130
|
+
If `mpy-cross` is not found, falls back to uploading `.py` with a warning.
|
|
131
|
+
|
|
108
132
|
### Move/rename on device
|
|
109
133
|
```
|
|
110
134
|
$ mpytool mv :/old.py :/new.py # rename file
|
|
@@ -139,8 +163,24 @@ $ mpytool cd :.. # change to parent directory
|
|
|
139
163
|
$ mpytool cd :/lib -- ls # change directory and list files
|
|
140
164
|
```
|
|
141
165
|
|
|
142
|
-
###
|
|
166
|
+
### Module search path (sys.path)
|
|
167
|
+
```
|
|
168
|
+
$ mpytool path # show current sys.path
|
|
169
|
+
'', '/lib'
|
|
170
|
+
$ mpytool path : :/lib # replace entire sys.path
|
|
171
|
+
$ mpytool path -f :/custom # prepend to sys.path (remove duplicates)
|
|
172
|
+
$ mpytool path -a :/sdcard/lib # append to sys.path (remove duplicates)
|
|
173
|
+
$ mpytool path -d :/custom # delete from sys.path
|
|
174
|
+
$ mpytool path -f : :/lib :/extra # prepend multiple paths
|
|
175
|
+
$ mpytool cd :/app -- path -f : # combine with cd to set working dir
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Path semantics: `:` = empty string (CWD) in sys.path, `:/` = root directory. The `-f` and `-a` flags automatically remove duplicates (move existing paths to new position).
|
|
179
|
+
|
|
180
|
+
### Stop, reset and REPL
|
|
143
181
|
```
|
|
182
|
+
$ mpytool stop # stop running program (Ctrl-C)
|
|
183
|
+
$ mpytool stop -- repl # stop and enter REPL
|
|
144
184
|
$ mpytool reset # soft reset (Ctrl-D, runs boot.py/main.py)
|
|
145
185
|
$ mpytool reset --raw # soft reset in raw REPL (clears RAM only)
|
|
146
186
|
$ mpytool reset --machine # MCU reset (machine.reset, auto-reconnect)
|
|
@@ -156,11 +196,18 @@ $ mpytool sleep 2 # sleep for 2 seconds (useful between commands)
|
|
|
156
196
|
### Serial terminal and monitor (general purpose)
|
|
157
197
|
```
|
|
158
198
|
$ mpytool repl # auto-detect port, 115200 baud
|
|
199
|
+
REPL (Ctrl+] to exit)
|
|
200
|
+
|
|
201
|
+
$ mpytool -v repl # verbose: shows CWD and sys.path before REPL
|
|
202
|
+
REPL (Ctrl+] to exit) CWD: / PATH: : :.frozen :/lib
|
|
203
|
+
|
|
159
204
|
$ mpytool -p /dev/ttyUSB0 repl # specify port
|
|
160
205
|
$ mpytool -b 9600 repl # specify baudrate
|
|
161
206
|
$ mpytool -p /dev/ttyUSB0 -b 9600 monitor # monitor at 9600 baud
|
|
162
207
|
```
|
|
163
208
|
|
|
209
|
+
The `repl` command with `-v` flag displays current working directory (CWD) and `sys.path` before entering REPL, making it easy to see the device state after `mount`, `cd`, or `path` commands.
|
|
210
|
+
|
|
164
211
|
Both `repl` and `monitor` can be used as general-purpose serial tools - not just for MicroPython devices. Use them to interact with any serial device (Arduino, ESP with custom firmware, GPS modules, etc.). When only one serial port is detected, it is used automatically. Default baudrate is 115200.
|
|
165
212
|
|
|
166
213
|
### Execute Python code on device
|
|
@@ -175,6 +222,121 @@ $ mpytool run script.py # run script (fire-and-forget)
|
|
|
175
222
|
$ mpytool run script.py -- monitor # run script and capture output
|
|
176
223
|
```
|
|
177
224
|
|
|
225
|
+
### Edit file on device
|
|
226
|
+
```
|
|
227
|
+
$ mpytool edit :boot.py # edit file (uses $VISUAL or $EDITOR)
|
|
228
|
+
$ mpytool edit :/lib/config.py # absolute path
|
|
229
|
+
$ mpytool edit --editor vim :main.py # explicit editor
|
|
230
|
+
$ mpytool edit :newfile.py # create new file if doesn't exist
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
Downloads file to a temp file, opens in editor, uploads back if changed.
|
|
234
|
+
Editor priority: `--editor` > `$VISUAL` > `$EDITOR` > error.
|
|
235
|
+
|
|
236
|
+
### Device RTC (real-time clock)
|
|
237
|
+
```
|
|
238
|
+
$ mpytool rtc # display current RTC
|
|
239
|
+
2026-02-21 15:30:45
|
|
240
|
+
|
|
241
|
+
$ mpytool rtc --set # set RTC to local PC time
|
|
242
|
+
RTC set to 2026-02-21 15:30:45 (local)
|
|
243
|
+
|
|
244
|
+
$ mpytool rtc --utc # set RTC to UTC time
|
|
245
|
+
RTC set to 2026-02-21 14:30:45 (UTC)
|
|
246
|
+
|
|
247
|
+
$ mpytool rtc "2026-02-21 14:30:00" # set RTC to specific datetime
|
|
248
|
+
RTC set to 2026-02-21 14:30:00
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
Flags: `-s`/`--set` and `-l`/`--local` both set local time, `-u`/`--utc` sets UTC.
|
|
252
|
+
Manual datetime format: `YYYY-MM-DD HH:MM:SS`.
|
|
253
|
+
|
|
254
|
+
### Mount local directory on device
|
|
255
|
+
```
|
|
256
|
+
$ mpytool mount ./src # mount ./src as /remote, auto-start REPL
|
|
257
|
+
Mounted ./src on /remote (readonly)
|
|
258
|
+
Changed CWD to /remote
|
|
259
|
+
REPL (Ctrl+] to exit)
|
|
260
|
+
|
|
261
|
+
$ mpytool -v mount ./src :/app # mount as /app instead of /remote (verbose)
|
|
262
|
+
Mounted ./src on /app (readonly)
|
|
263
|
+
Changed CWD to /app
|
|
264
|
+
REPL (Ctrl+] to exit) CWD: /app PATH: : :.frozen :/lib
|
|
265
|
+
|
|
266
|
+
$ mpytool mount -m ./src :/app # mount with automatic .mpy compilation
|
|
267
|
+
Mounted ./src on /app (readonly, .mpy compilation)
|
|
268
|
+
Changed CWD to /app
|
|
269
|
+
>>> import foo # imports /app/foo.mpy (compiled from ./src/foo.py)
|
|
270
|
+
|
|
271
|
+
$ mpytool mount -w ./workspace :/work # mount as read-write (can create/modify/delete files)
|
|
272
|
+
Mounted ./workspace on /work (read-write)
|
|
273
|
+
Changed CWD to /work
|
|
274
|
+
>>> f = open('/work/test.txt', 'w'); f.write('hello'); f.close() # creates local file
|
|
275
|
+
>>> import os; os.mkdir('/work/newdir') # creates local directory
|
|
276
|
+
|
|
277
|
+
$ mpytool mount ./src -- exec "import main" # mount and run code
|
|
278
|
+
$ mpytool mount ./src -- monitor # mount and monitor output
|
|
279
|
+
$ mpytool mount ./app :/app -- mount ./lib :/lib -- repl # multiple mounts (CWD = /app)
|
|
280
|
+
Mounted ./app on /app (readonly)
|
|
281
|
+
Changed CWD to /app
|
|
282
|
+
Mounted ./lib on /lib (readonly)
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
Mounts a local directory on the device as a VFS. The device can read,
|
|
286
|
+
import and execute files from the local directory without uploading
|
|
287
|
+
them to flash. Changes to local files are immediately visible on
|
|
288
|
+
the device.
|
|
289
|
+
|
|
290
|
+
**Memory overhead:** The VFS agent uses ~4.2KB of RAM on the device
|
|
291
|
+
(154 lines of MicroPython code injected during mount).
|
|
292
|
+
|
|
293
|
+
**By default, mounts are read-only.** Use `-w` / `--writable` flag
|
|
294
|
+
to enable write support — the device can create, modify and delete
|
|
295
|
+
files in the mounted directory. All changes are written directly to
|
|
296
|
+
the local filesystem.
|
|
297
|
+
|
|
298
|
+
**`-m` / `--mpy` flag:** Enables transparent `.mpy` compilation.
|
|
299
|
+
When the device imports a module, the `.py` file is automatically
|
|
300
|
+
compiled to `.mpy` bytecode on-demand and served from cache
|
|
301
|
+
(`__pycache__/`). Benefits: faster imports, less RAM usage, support
|
|
302
|
+
for `@native`/`@viper` code with `-march`. Boot files (`boot.py`,
|
|
303
|
+
`main.py`) and empty files remain as `.py`. If compilation fails,
|
|
304
|
+
automatically falls back to `.py`. Prebuilt `.mpy` files have
|
|
305
|
+
priority over cache.
|
|
306
|
+
|
|
307
|
+
The first mount automatically changes CWD to the mount point (mpremote
|
|
308
|
+
compatibility). Subsequent mounts do not change CWD. Use `cd` command
|
|
309
|
+
to change working directory manually if needed. Multiple independent
|
|
310
|
+
(non-nested) mounts are supported.
|
|
311
|
+
|
|
312
|
+
After mount, mpytool automatically enters REPL (unless `monitor` or
|
|
313
|
+
`repl` follows). In REPL you can import modules from the mounted
|
|
314
|
+
directory, Ctrl+D triggers soft reset with automatic re-mount and CWD
|
|
315
|
+
restoration to the mount point.
|
|
316
|
+
|
|
317
|
+
**Best for:** Development, testing, prototyping, debugging. For bulk
|
|
318
|
+
file transfers (uploading/downloading many files), use `cp` command
|
|
319
|
+
instead — it's optimized for throughput.
|
|
320
|
+
|
|
321
|
+
**Security:** Paths are validated to prevent traversal outside mount
|
|
322
|
+
root. Symlinks are followed and checked. Write operations require
|
|
323
|
+
explicit `-w` flag.
|
|
324
|
+
|
|
325
|
+
See [Mount VFS Comparison](README_mpremote.md#mount-vfs-comparison) for detailed comparison with mpremote.
|
|
326
|
+
|
|
327
|
+
### Link files into mounted VFS
|
|
328
|
+
```
|
|
329
|
+
$ mpytool mount ./app :/ -- ln ./drivers :/lib/ -- repl # mount app, link drivers into /lib/
|
|
330
|
+
$ mpytool mount ./app :/ -- ln ./extra.py :/lib/ -- repl # link single file into /lib/
|
|
331
|
+
$ mpytool mount ./app :/ -- ln ./pkg :/lib/pkg -- repl # link as specific name
|
|
332
|
+
$ mpytool mount ./app :/ -- ln ./pkg/ :/lib/ -- repl # link package contents into /lib/
|
|
333
|
+
$ mpytool mount ./app :/ -- ln ./a.py ./b.py :/lib/ -- repl # link multiple sources
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
Links local files or directories into an already mounted VFS as virtual submounts. Works entirely on the PC side — no changes needed on the device. Useful for composing a virtual filesystem from multiple local directories without copying.
|
|
337
|
+
|
|
338
|
+
Path semantics follow the same trailing `/` rules as `cp`: `ln dir :/lib/` creates `:/lib/dir/...`, `ln dir/ :/lib/` copies contents into `:/lib/...`. Destination must be an absolute device path with `:` prefix.
|
|
339
|
+
|
|
178
340
|
### Serial link speed test
|
|
179
341
|
```
|
|
180
342
|
$ mpytool speedtest
|
|
@@ -234,9 +396,9 @@ $ mpytool flash erase vfs --full # full erase partition
|
|
|
234
396
|
|
|
235
397
|
### OTA firmware update (ESP32)
|
|
236
398
|
```
|
|
237
|
-
$ mpytool ota firmware.app-bin # flash to next OTA partition
|
|
238
|
-
$ mpytool ota firmware.app-bin -- reset --machine # flash and reboot
|
|
239
|
-
$ mpytool ota firmware.app-bin -- reset --machine -t 30 # flash and reboot with 30s timeout
|
|
399
|
+
$ mpytool flash ota firmware.app-bin # flash to next OTA partition
|
|
400
|
+
$ mpytool flash ota firmware.app-bin -- reset --machine # flash and reboot
|
|
401
|
+
$ mpytool flash ota firmware.app-bin -- reset --machine -t 30 # flash and reboot with 30s timeout
|
|
240
402
|
```
|
|
241
403
|
|
|
242
404
|
### Multiple commands separated by `--`
|
|
@@ -364,7 +526,7 @@ For reporting bugs, please include `-ddd` output in the issue.
|
|
|
364
526
|
|
|
365
527
|
## Performance
|
|
366
528
|
|
|
367
|
-
`mpytool` uses optimized chunked transfer with automatic compression, which allows copying files very quickly. See [
|
|
529
|
+
`mpytool` uses optimized chunked transfer with automatic compression, which allows copying files very quickly. See [README_bench.md](README_bench.md) for detailed benchmarks.
|
|
368
530
|
|
|
369
531
|
### Summary
|
|
370
532
|
|
|
@@ -4,5 +4,5 @@ from mpytool.conn import ConnError, Timeout
|
|
|
4
4
|
from mpytool.conn_serial import ConnSerial
|
|
5
5
|
from mpytool.conn_socket import ConnSocket
|
|
6
6
|
from mpytool.mpy_comm import MpyError, CmdError
|
|
7
|
-
from mpytool.mpy import Mpy
|
|
7
|
+
from mpytool.mpy import Mpy, PathNotFound, FileNotFound, DirNotFound
|
|
8
8
|
from mpytool.logger import SimpleColorLogger
|