mpytool 2.3.0__tar.gz → 2.3.2__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.3.0 → mpytool-2.3.2}/PKG-INFO +142 -34
- {mpytool-2.3.0 → mpytool-2.3.2}/README.md +141 -33
- {mpytool-2.3.0 → mpytool-2.3.2}/mpytool/cmd_cp.py +1 -4
- {mpytool-2.3.0 → mpytool-2.3.2}/mpytool/conn_serial.py +49 -27
- {mpytool-2.3.0 → mpytool-2.3.2}/mpytool/logger.py +16 -2
- {mpytool-2.3.0 → mpytool-2.3.2}/mpytool/mount.py +126 -32
- {mpytool-2.3.0 → mpytool-2.3.2}/mpytool/mpytool.py +83 -44
- mpytool-2.3.2/mpytool/utils.py +136 -0
- {mpytool-2.3.0 → mpytool-2.3.2}/mpytool.egg-info/PKG-INFO +142 -34
- {mpytool-2.3.0 → mpytool-2.3.2}/mpytool.egg-info/SOURCES.txt +1 -0
- {mpytool-2.3.0 → mpytool-2.3.2}/pyproject.toml +1 -1
- mpytool-2.3.2/tests/test_cli.py +634 -0
- {mpytool-2.3.0 → mpytool-2.3.2}/tests/test_integration.py +58 -32
- {mpytool-2.3.0 → mpytool-2.3.2}/tests/test_mpytool.py +2 -0
- {mpytool-2.3.0 → mpytool-2.3.2}/tests/test_utils.py +81 -36
- mpytool-2.3.0/mpytool/utils.py +0 -100
- {mpytool-2.3.0 → mpytool-2.3.2}/LICENSE +0 -0
- {mpytool-2.3.0 → mpytool-2.3.2}/mpytool/__init__.py +0 -0
- {mpytool-2.3.0 → mpytool-2.3.2}/mpytool/conn.py +0 -0
- {mpytool-2.3.0 → mpytool-2.3.2}/mpytool/conn_socket.py +0 -0
- {mpytool-2.3.0 → mpytool-2.3.2}/mpytool/mpy.py +0 -0
- {mpytool-2.3.0 → mpytool-2.3.2}/mpytool/mpy_comm.py +0 -0
- {mpytool-2.3.0 → mpytool-2.3.2}/mpytool/mpy_cross.py +0 -0
- {mpytool-2.3.0 → mpytool-2.3.2}/mpytool/speedtest.py +0 -0
- {mpytool-2.3.0 → mpytool-2.3.2}/mpytool/terminal.py +0 -0
- {mpytool-2.3.0 → mpytool-2.3.2}/mpytool/terminal_unix.py +0 -0
- {mpytool-2.3.0 → mpytool-2.3.2}/mpytool/terminal_win.py +0 -0
- {mpytool-2.3.0 → mpytool-2.3.2}/mpytool.egg-info/dependency_links.txt +0 -0
- {mpytool-2.3.0 → mpytool-2.3.2}/mpytool.egg-info/entry_points.txt +0 -0
- {mpytool-2.3.0 → mpytool-2.3.2}/mpytool.egg-info/requires.txt +0 -0
- {mpytool-2.3.0 → mpytool-2.3.2}/mpytool.egg-info/top_level.txt +0 -0
- {mpytool-2.3.0 → mpytool-2.3.2}/setup.cfg +0 -0
- {mpytool-2.3.0 → mpytool-2.3.2}/tests/test_cmd_cp.py +0 -0
- {mpytool-2.3.0 → mpytool-2.3.2}/tests/test_errors.py +0 -0
- {mpytool-2.3.0 → mpytool-2.3.2}/tests/test_mount.py +0 -0
- {mpytool-2.3.0 → mpytool-2.3.2}/tests/test_mpy.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mpytool
|
|
3
|
-
Version: 2.3.
|
|
3
|
+
Version: 2.3.2
|
|
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
|
|
@@ -42,6 +42,7 @@ It is an alternative to the official [mpremote](https://docs.micropython.org/en/
|
|
|
42
42
|
RAM usage (API)
|
|
43
43
|
- **Shell completion** - ZSH and Bash with remote path completion
|
|
44
44
|
- **Network support** - connect over TCP
|
|
45
|
+
- **Full Unicode support** - handles Unicode in file names and content
|
|
45
46
|
|
|
46
47
|
See [README_mpremote.md](README_mpremote.md) for detailed comparison with mpremote.
|
|
47
48
|
|
|
@@ -97,13 +98,34 @@ $ mpytool --help
|
|
|
97
98
|
|
|
98
99
|
### List files
|
|
99
100
|
```
|
|
100
|
-
$ mpytool -p /dev/ttyACM0 ls # list CWD (default)
|
|
101
|
-
|
|
101
|
+
$ mpytool -p /dev/ttyACM0 ls # Linux: list CWD (default)
|
|
102
|
+
LS: /
|
|
103
|
+
215B boot.py
|
|
104
|
+
3.03K main.py
|
|
105
|
+
lib/
|
|
106
|
+
|
|
107
|
+
$ mpytool ls :/lib # list /lib (auto-detect port)
|
|
108
|
+
LS: /lib
|
|
109
|
+
uhttp/
|
|
110
|
+
23.1K wlan.py
|
|
111
|
+
|
|
112
|
+
$ mpytool ls :/data # Unicode file names supported
|
|
113
|
+
LS: /data
|
|
114
|
+
64B データ.csv
|
|
115
|
+
32B 🍅.py
|
|
116
|
+
128B súbor.txt
|
|
117
|
+
256B 配置.json
|
|
102
118
|
```
|
|
103
119
|
|
|
104
120
|
### Tree
|
|
105
121
|
```
|
|
106
|
-
$ mpytool -p /dev/
|
|
122
|
+
$ mpytool -p /dev/cu.usbmodem1101 tree # macOS: tree of CWD
|
|
123
|
+
TREE: /
|
|
124
|
+
142K ./
|
|
125
|
+
97.7K ├─ lib/
|
|
126
|
+
69.6K │ └─ uhttp/
|
|
127
|
+
23 ├─ boot.py
|
|
128
|
+
3.03K └─ main.py
|
|
107
129
|
```
|
|
108
130
|
|
|
109
131
|
### Copy files (: prefix = device path)
|
|
@@ -153,40 +175,70 @@ $ mpytool mv :/a.py :/b.py :/lib/ # move multiple files to directory
|
|
|
153
175
|
### View file contents
|
|
154
176
|
```
|
|
155
177
|
$ mpytool cat :boot.py # print file from CWD
|
|
178
|
+
CAT: /boot.py
|
|
179
|
+
import machine
|
|
180
|
+
...
|
|
181
|
+
|
|
156
182
|
$ mpytool cat :/lib/module.py # print file with absolute path
|
|
183
|
+
CAT: /lib/module.py
|
|
184
|
+
def hello():
|
|
185
|
+
print("Hello!")
|
|
157
186
|
```
|
|
158
187
|
|
|
159
188
|
### Make directory, delete files (: prefix = device path)
|
|
160
189
|
```
|
|
161
190
|
$ mpytool mkdir :lib :data # create directories in CWD
|
|
191
|
+
MKDIR: /lib
|
|
192
|
+
MKDIR: /data
|
|
193
|
+
|
|
162
194
|
$ mpytool mkdir :/lib/subdir # create with absolute path
|
|
195
|
+
MKDIR: /lib/subdir
|
|
196
|
+
|
|
163
197
|
$ mpytool rm :old.py # delete file in CWD
|
|
198
|
+
RM: /old.py
|
|
199
|
+
|
|
164
200
|
$ mpytool rm :mydir # delete directory and contents
|
|
201
|
+
RM: /mydir
|
|
202
|
+
|
|
165
203
|
$ mpytool rm :mydir/ # delete contents only, keep directory
|
|
166
|
-
|
|
167
|
-
$ mpytool rm :/ # delete everything on device (root)
|
|
204
|
+
RM contents: /mydir
|
|
168
205
|
```
|
|
169
206
|
|
|
170
207
|
### Current working directory
|
|
171
208
|
```
|
|
172
209
|
$ mpytool pwd # print current directory
|
|
210
|
+
PWD
|
|
173
211
|
/
|
|
212
|
+
|
|
174
213
|
$ mpytool cd :/lib # change to /lib
|
|
214
|
+
CD: /lib
|
|
215
|
+
|
|
175
216
|
$ mpytool cd :subdir # change to relative path (from CWD)
|
|
176
|
-
|
|
217
|
+
CD: /lib/subdir
|
|
218
|
+
|
|
177
219
|
$ mpytool cd :/lib -- ls # change directory and list files
|
|
220
|
+
CD: /lib
|
|
221
|
+
LS: /lib
|
|
222
|
+
uhttp/
|
|
223
|
+
23.1K wlan.py
|
|
178
224
|
```
|
|
179
225
|
|
|
180
226
|
### Module search path (sys.path)
|
|
181
227
|
```
|
|
182
228
|
$ mpytool path # show current sys.path
|
|
183
|
-
|
|
229
|
+
: :/lib
|
|
230
|
+
|
|
184
231
|
$ mpytool path : :/lib # replace entire sys.path
|
|
232
|
+
PATH set to 2 entries
|
|
233
|
+
|
|
185
234
|
$ mpytool path -f :/custom # prepend to sys.path (remove duplicates)
|
|
235
|
+
PATH prepended 1 entries
|
|
236
|
+
|
|
186
237
|
$ mpytool path -a :/sdcard/lib # append to sys.path (remove duplicates)
|
|
238
|
+
PATH appended 1 entries
|
|
239
|
+
|
|
187
240
|
$ mpytool path -d :/custom # delete from sys.path
|
|
188
|
-
|
|
189
|
-
$ mpytool cd :/app -- path -f : # combine with cd to set working dir
|
|
241
|
+
PATH removed 1 entries
|
|
190
242
|
```
|
|
191
243
|
|
|
192
244
|
Path semantics: `:` = empty string (CWD) in sys.path, `:/` = root directory. The `-f` and `-a` flags automatically remove duplicates (move existing paths to new position).
|
|
@@ -194,17 +246,23 @@ Path semantics: `:` = empty string (CWD) in sys.path, `:/` = root directory. The
|
|
|
194
246
|
### Stop, reset and REPL
|
|
195
247
|
```
|
|
196
248
|
$ mpytool stop # stop running program (Ctrl-C)
|
|
197
|
-
|
|
249
|
+
STOP
|
|
250
|
+
|
|
198
251
|
$ mpytool reset # soft reset (Ctrl-D, runs boot.py/main.py)
|
|
199
|
-
|
|
252
|
+
RESET soft
|
|
253
|
+
|
|
200
254
|
$ mpytool reset --machine # MCU reset (machine.reset, auto-reconnect)
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
$ mpytool reset --boot # enter bootloader (machine.bootloader)
|
|
204
|
-
$ mpytool reset --dtr-boot # enter bootloader via DTR/RTS (ESP32 only)
|
|
255
|
+
RESET machine
|
|
256
|
+
|
|
205
257
|
$ mpytool reset -- monitor # reset and monitor output
|
|
258
|
+
RESET soft
|
|
259
|
+
MONITOR (Ctrl+C to stop)
|
|
260
|
+
|
|
206
261
|
$ mpytool repl # enter REPL mode
|
|
262
|
+
REPL (Ctrl+] to exit)
|
|
263
|
+
|
|
207
264
|
$ mpytool sleep 2 # sleep for 2 seconds (useful between commands)
|
|
265
|
+
SLEEP 2.0s
|
|
208
266
|
```
|
|
209
267
|
|
|
210
268
|
### Serial terminal and monitor (general purpose)
|
|
@@ -227,21 +285,35 @@ Both `repl` and `monitor` can be used as general-purpose serial tools - not just
|
|
|
227
285
|
### Execute Python code on device
|
|
228
286
|
```
|
|
229
287
|
$ mpytool exec "print('Hello!')"
|
|
288
|
+
EXEC: print('Hello!')
|
|
289
|
+
Hello!
|
|
290
|
+
|
|
230
291
|
$ mpytool exec "import sys; print(sys.version)"
|
|
292
|
+
EXEC: import sys; print(sys.version)
|
|
293
|
+
3.4.0; MicroPython v1.24.0
|
|
231
294
|
```
|
|
232
295
|
|
|
233
296
|
### Run local Python file on device
|
|
234
297
|
```
|
|
235
298
|
$ mpytool run script.py # run script (fire-and-forget)
|
|
299
|
+
RUN: script.py (128 bytes)
|
|
300
|
+
|
|
236
301
|
$ mpytool run script.py -- monitor # run script and capture output
|
|
302
|
+
RUN: script.py (128 bytes)
|
|
303
|
+
MONITOR (Ctrl+C to stop)
|
|
304
|
+
Hello from script!
|
|
237
305
|
```
|
|
238
306
|
|
|
239
307
|
### Edit file on device
|
|
240
308
|
```
|
|
241
309
|
$ mpytool edit :boot.py # edit file (uses $VISUAL or $EDITOR)
|
|
310
|
+
EDIT: /boot.py
|
|
311
|
+
|
|
242
312
|
$ mpytool edit :/lib/config.py # absolute path
|
|
243
|
-
|
|
313
|
+
EDIT: /lib/config.py
|
|
314
|
+
|
|
244
315
|
$ mpytool edit :newfile.py # create new file if doesn't exist
|
|
316
|
+
EDIT: /newfile.py (new file)
|
|
245
317
|
```
|
|
246
318
|
|
|
247
319
|
Downloads file to a temp file, opens in editor, uploads back if changed.
|
|
@@ -250,6 +322,7 @@ Editor priority: `--editor` > `$VISUAL` > `$EDITOR` > error.
|
|
|
250
322
|
### Device RTC (real-time clock)
|
|
251
323
|
```
|
|
252
324
|
$ mpytool rtc # display current RTC
|
|
325
|
+
RTC
|
|
253
326
|
2026-02-21 15:30:45
|
|
254
327
|
|
|
255
328
|
$ mpytool rtc --set # set RTC to local PC time
|
|
@@ -366,7 +439,8 @@ SPEEDTEST
|
|
|
366
439
|
|
|
367
440
|
### Show device information
|
|
368
441
|
```
|
|
369
|
-
$ mpytool info
|
|
442
|
+
$ mpytool -p COM3 info # Windows
|
|
443
|
+
INFO
|
|
370
444
|
Platform: rp2
|
|
371
445
|
Version: 3.4.0; MicroPython v1.27.0 on 2025-12-09
|
|
372
446
|
Impl: micropython
|
|
@@ -423,28 +497,30 @@ $ mpytool rm :old.py -- cp new.py : -- reset
|
|
|
423
497
|
|
|
424
498
|
### Auto-detect serial port (if only one device is connected)
|
|
425
499
|
```
|
|
426
|
-
$ mpytool ls lib
|
|
500
|
+
$ mpytool ls :/lib
|
|
501
|
+
LS: /lib
|
|
427
502
|
uhttp/
|
|
428
|
-
|
|
429
|
-
|
|
503
|
+
23.1K wlan.py
|
|
504
|
+
4.95K wlan_http.py
|
|
430
505
|
```
|
|
431
506
|
|
|
432
507
|
### Tree view
|
|
433
508
|
```
|
|
434
509
|
$ mpytool tree
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
510
|
+
TREE: /
|
|
511
|
+
142K ./
|
|
512
|
+
41.3K ├─ html/
|
|
513
|
+
587 │ ├─ index.html
|
|
514
|
+
40.8K │ └─ wlan.html
|
|
515
|
+
97.7K ├─ lib/
|
|
516
|
+
69.6K │ ├─ uhttp/
|
|
517
|
+
93 │ │ ├─ __init__.py
|
|
518
|
+
26.3K │ │ ├─ client.py
|
|
519
|
+
43.2K │ │ └─ server.py
|
|
520
|
+
23.1K │ ├─ wlan.py
|
|
521
|
+
4.95K │ └─ wlan_http.py
|
|
522
|
+
23 ├─ boot.py
|
|
523
|
+
3.03K └─ main.py
|
|
448
524
|
```
|
|
449
525
|
|
|
450
526
|
### Connect over network (TCP, default port 23)
|
|
@@ -616,6 +692,38 @@ exec bash
|
|
|
616
692
|
- Support for `--` command separator
|
|
617
693
|
- Works with both relative and absolute paths
|
|
618
694
|
|
|
695
|
+
## Development
|
|
696
|
+
|
|
697
|
+
### Running tests
|
|
698
|
+
|
|
699
|
+
```bash
|
|
700
|
+
# Unit tests (no device needed)
|
|
701
|
+
python -m unittest discover tests/ -v
|
|
702
|
+
|
|
703
|
+
# Read-only integration tests (safe on production device)
|
|
704
|
+
MPYTOOL_TEST_PORT=/dev/ttyACM0 python -m unittest tests.test_integration -v
|
|
705
|
+
|
|
706
|
+
# All integration tests (dedicated test device)
|
|
707
|
+
MPYTOOL_TEST_PORT_RW=/dev/ttyACM0 python -m unittest tests.test_integration -v
|
|
708
|
+
|
|
709
|
+
# CLI tests (no device needed for basic tests)
|
|
710
|
+
python -m unittest tests.test_cli -v
|
|
711
|
+
|
|
712
|
+
# All CLI tests with device
|
|
713
|
+
MPYTOOL_TEST_PORT_RW=/dev/ttyACM0 python -m unittest tests.test_cli -v
|
|
714
|
+
```
|
|
715
|
+
|
|
716
|
+
Test categories:
|
|
717
|
+
- **Unit tests** (`test_*.py` except `test_integration.py`, `test_cli.py`) - no device needed
|
|
718
|
+
- **Read-only tests** (`MPYTOOL_TEST_PORT`) - safe on any device, no filesystem changes
|
|
719
|
+
- **All tests** (`MPYTOOL_TEST_PORT_RW`) - includes write and flash operations, use dedicated test device
|
|
720
|
+
|
|
721
|
+
### Install from source
|
|
722
|
+
|
|
723
|
+
```bash
|
|
724
|
+
pip install -e .
|
|
725
|
+
```
|
|
726
|
+
|
|
619
727
|
## Requirements
|
|
620
728
|
|
|
621
729
|
Working only with MicroPython boards, not with CircuitPython
|
|
@@ -28,6 +28,7 @@ It is an alternative to the official [mpremote](https://docs.micropython.org/en/
|
|
|
28
28
|
RAM usage (API)
|
|
29
29
|
- **Shell completion** - ZSH and Bash with remote path completion
|
|
30
30
|
- **Network support** - connect over TCP
|
|
31
|
+
- **Full Unicode support** - handles Unicode in file names and content
|
|
31
32
|
|
|
32
33
|
See [README_mpremote.md](README_mpremote.md) for detailed comparison with mpremote.
|
|
33
34
|
|
|
@@ -83,13 +84,34 @@ $ mpytool --help
|
|
|
83
84
|
|
|
84
85
|
### List files
|
|
85
86
|
```
|
|
86
|
-
$ mpytool -p /dev/ttyACM0 ls # list CWD (default)
|
|
87
|
-
|
|
87
|
+
$ mpytool -p /dev/ttyACM0 ls # Linux: list CWD (default)
|
|
88
|
+
LS: /
|
|
89
|
+
215B boot.py
|
|
90
|
+
3.03K main.py
|
|
91
|
+
lib/
|
|
92
|
+
|
|
93
|
+
$ mpytool ls :/lib # list /lib (auto-detect port)
|
|
94
|
+
LS: /lib
|
|
95
|
+
uhttp/
|
|
96
|
+
23.1K wlan.py
|
|
97
|
+
|
|
98
|
+
$ mpytool ls :/data # Unicode file names supported
|
|
99
|
+
LS: /data
|
|
100
|
+
64B データ.csv
|
|
101
|
+
32B 🍅.py
|
|
102
|
+
128B súbor.txt
|
|
103
|
+
256B 配置.json
|
|
88
104
|
```
|
|
89
105
|
|
|
90
106
|
### Tree
|
|
91
107
|
```
|
|
92
|
-
$ mpytool -p /dev/
|
|
108
|
+
$ mpytool -p /dev/cu.usbmodem1101 tree # macOS: tree of CWD
|
|
109
|
+
TREE: /
|
|
110
|
+
142K ./
|
|
111
|
+
97.7K ├─ lib/
|
|
112
|
+
69.6K │ └─ uhttp/
|
|
113
|
+
23 ├─ boot.py
|
|
114
|
+
3.03K └─ main.py
|
|
93
115
|
```
|
|
94
116
|
|
|
95
117
|
### Copy files (: prefix = device path)
|
|
@@ -139,40 +161,70 @@ $ mpytool mv :/a.py :/b.py :/lib/ # move multiple files to directory
|
|
|
139
161
|
### View file contents
|
|
140
162
|
```
|
|
141
163
|
$ mpytool cat :boot.py # print file from CWD
|
|
164
|
+
CAT: /boot.py
|
|
165
|
+
import machine
|
|
166
|
+
...
|
|
167
|
+
|
|
142
168
|
$ mpytool cat :/lib/module.py # print file with absolute path
|
|
169
|
+
CAT: /lib/module.py
|
|
170
|
+
def hello():
|
|
171
|
+
print("Hello!")
|
|
143
172
|
```
|
|
144
173
|
|
|
145
174
|
### Make directory, delete files (: prefix = device path)
|
|
146
175
|
```
|
|
147
176
|
$ mpytool mkdir :lib :data # create directories in CWD
|
|
177
|
+
MKDIR: /lib
|
|
178
|
+
MKDIR: /data
|
|
179
|
+
|
|
148
180
|
$ mpytool mkdir :/lib/subdir # create with absolute path
|
|
181
|
+
MKDIR: /lib/subdir
|
|
182
|
+
|
|
149
183
|
$ mpytool rm :old.py # delete file in CWD
|
|
184
|
+
RM: /old.py
|
|
185
|
+
|
|
150
186
|
$ mpytool rm :mydir # delete directory and contents
|
|
187
|
+
RM: /mydir
|
|
188
|
+
|
|
151
189
|
$ mpytool rm :mydir/ # delete contents only, keep directory
|
|
152
|
-
|
|
153
|
-
$ mpytool rm :/ # delete everything on device (root)
|
|
190
|
+
RM contents: /mydir
|
|
154
191
|
```
|
|
155
192
|
|
|
156
193
|
### Current working directory
|
|
157
194
|
```
|
|
158
195
|
$ mpytool pwd # print current directory
|
|
196
|
+
PWD
|
|
159
197
|
/
|
|
198
|
+
|
|
160
199
|
$ mpytool cd :/lib # change to /lib
|
|
200
|
+
CD: /lib
|
|
201
|
+
|
|
161
202
|
$ mpytool cd :subdir # change to relative path (from CWD)
|
|
162
|
-
|
|
203
|
+
CD: /lib/subdir
|
|
204
|
+
|
|
163
205
|
$ mpytool cd :/lib -- ls # change directory and list files
|
|
206
|
+
CD: /lib
|
|
207
|
+
LS: /lib
|
|
208
|
+
uhttp/
|
|
209
|
+
23.1K wlan.py
|
|
164
210
|
```
|
|
165
211
|
|
|
166
212
|
### Module search path (sys.path)
|
|
167
213
|
```
|
|
168
214
|
$ mpytool path # show current sys.path
|
|
169
|
-
|
|
215
|
+
: :/lib
|
|
216
|
+
|
|
170
217
|
$ mpytool path : :/lib # replace entire sys.path
|
|
218
|
+
PATH set to 2 entries
|
|
219
|
+
|
|
171
220
|
$ mpytool path -f :/custom # prepend to sys.path (remove duplicates)
|
|
221
|
+
PATH prepended 1 entries
|
|
222
|
+
|
|
172
223
|
$ mpytool path -a :/sdcard/lib # append to sys.path (remove duplicates)
|
|
224
|
+
PATH appended 1 entries
|
|
225
|
+
|
|
173
226
|
$ mpytool path -d :/custom # delete from sys.path
|
|
174
|
-
|
|
175
|
-
$ mpytool cd :/app -- path -f : # combine with cd to set working dir
|
|
227
|
+
PATH removed 1 entries
|
|
176
228
|
```
|
|
177
229
|
|
|
178
230
|
Path semantics: `:` = empty string (CWD) in sys.path, `:/` = root directory. The `-f` and `-a` flags automatically remove duplicates (move existing paths to new position).
|
|
@@ -180,17 +232,23 @@ Path semantics: `:` = empty string (CWD) in sys.path, `:/` = root directory. The
|
|
|
180
232
|
### Stop, reset and REPL
|
|
181
233
|
```
|
|
182
234
|
$ mpytool stop # stop running program (Ctrl-C)
|
|
183
|
-
|
|
235
|
+
STOP
|
|
236
|
+
|
|
184
237
|
$ mpytool reset # soft reset (Ctrl-D, runs boot.py/main.py)
|
|
185
|
-
|
|
238
|
+
RESET soft
|
|
239
|
+
|
|
186
240
|
$ mpytool reset --machine # MCU reset (machine.reset, auto-reconnect)
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
$ mpytool reset --boot # enter bootloader (machine.bootloader)
|
|
190
|
-
$ mpytool reset --dtr-boot # enter bootloader via DTR/RTS (ESP32 only)
|
|
241
|
+
RESET machine
|
|
242
|
+
|
|
191
243
|
$ mpytool reset -- monitor # reset and monitor output
|
|
244
|
+
RESET soft
|
|
245
|
+
MONITOR (Ctrl+C to stop)
|
|
246
|
+
|
|
192
247
|
$ mpytool repl # enter REPL mode
|
|
248
|
+
REPL (Ctrl+] to exit)
|
|
249
|
+
|
|
193
250
|
$ mpytool sleep 2 # sleep for 2 seconds (useful between commands)
|
|
251
|
+
SLEEP 2.0s
|
|
194
252
|
```
|
|
195
253
|
|
|
196
254
|
### Serial terminal and monitor (general purpose)
|
|
@@ -213,21 +271,35 @@ Both `repl` and `monitor` can be used as general-purpose serial tools - not just
|
|
|
213
271
|
### Execute Python code on device
|
|
214
272
|
```
|
|
215
273
|
$ mpytool exec "print('Hello!')"
|
|
274
|
+
EXEC: print('Hello!')
|
|
275
|
+
Hello!
|
|
276
|
+
|
|
216
277
|
$ mpytool exec "import sys; print(sys.version)"
|
|
278
|
+
EXEC: import sys; print(sys.version)
|
|
279
|
+
3.4.0; MicroPython v1.24.0
|
|
217
280
|
```
|
|
218
281
|
|
|
219
282
|
### Run local Python file on device
|
|
220
283
|
```
|
|
221
284
|
$ mpytool run script.py # run script (fire-and-forget)
|
|
285
|
+
RUN: script.py (128 bytes)
|
|
286
|
+
|
|
222
287
|
$ mpytool run script.py -- monitor # run script and capture output
|
|
288
|
+
RUN: script.py (128 bytes)
|
|
289
|
+
MONITOR (Ctrl+C to stop)
|
|
290
|
+
Hello from script!
|
|
223
291
|
```
|
|
224
292
|
|
|
225
293
|
### Edit file on device
|
|
226
294
|
```
|
|
227
295
|
$ mpytool edit :boot.py # edit file (uses $VISUAL or $EDITOR)
|
|
296
|
+
EDIT: /boot.py
|
|
297
|
+
|
|
228
298
|
$ mpytool edit :/lib/config.py # absolute path
|
|
229
|
-
|
|
299
|
+
EDIT: /lib/config.py
|
|
300
|
+
|
|
230
301
|
$ mpytool edit :newfile.py # create new file if doesn't exist
|
|
302
|
+
EDIT: /newfile.py (new file)
|
|
231
303
|
```
|
|
232
304
|
|
|
233
305
|
Downloads file to a temp file, opens in editor, uploads back if changed.
|
|
@@ -236,6 +308,7 @@ Editor priority: `--editor` > `$VISUAL` > `$EDITOR` > error.
|
|
|
236
308
|
### Device RTC (real-time clock)
|
|
237
309
|
```
|
|
238
310
|
$ mpytool rtc # display current RTC
|
|
311
|
+
RTC
|
|
239
312
|
2026-02-21 15:30:45
|
|
240
313
|
|
|
241
314
|
$ mpytool rtc --set # set RTC to local PC time
|
|
@@ -352,7 +425,8 @@ SPEEDTEST
|
|
|
352
425
|
|
|
353
426
|
### Show device information
|
|
354
427
|
```
|
|
355
|
-
$ mpytool info
|
|
428
|
+
$ mpytool -p COM3 info # Windows
|
|
429
|
+
INFO
|
|
356
430
|
Platform: rp2
|
|
357
431
|
Version: 3.4.0; MicroPython v1.27.0 on 2025-12-09
|
|
358
432
|
Impl: micropython
|
|
@@ -409,28 +483,30 @@ $ mpytool rm :old.py -- cp new.py : -- reset
|
|
|
409
483
|
|
|
410
484
|
### Auto-detect serial port (if only one device is connected)
|
|
411
485
|
```
|
|
412
|
-
$ mpytool ls lib
|
|
486
|
+
$ mpytool ls :/lib
|
|
487
|
+
LS: /lib
|
|
413
488
|
uhttp/
|
|
414
|
-
|
|
415
|
-
|
|
489
|
+
23.1K wlan.py
|
|
490
|
+
4.95K wlan_http.py
|
|
416
491
|
```
|
|
417
492
|
|
|
418
493
|
### Tree view
|
|
419
494
|
```
|
|
420
495
|
$ mpytool tree
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
496
|
+
TREE: /
|
|
497
|
+
142K ./
|
|
498
|
+
41.3K ├─ html/
|
|
499
|
+
587 │ ├─ index.html
|
|
500
|
+
40.8K │ └─ wlan.html
|
|
501
|
+
97.7K ├─ lib/
|
|
502
|
+
69.6K │ ├─ uhttp/
|
|
503
|
+
93 │ │ ├─ __init__.py
|
|
504
|
+
26.3K │ │ ├─ client.py
|
|
505
|
+
43.2K │ │ └─ server.py
|
|
506
|
+
23.1K │ ├─ wlan.py
|
|
507
|
+
4.95K │ └─ wlan_http.py
|
|
508
|
+
23 ├─ boot.py
|
|
509
|
+
3.03K └─ main.py
|
|
434
510
|
```
|
|
435
511
|
|
|
436
512
|
### Connect over network (TCP, default port 23)
|
|
@@ -602,6 +678,38 @@ exec bash
|
|
|
602
678
|
- Support for `--` command separator
|
|
603
679
|
- Works with both relative and absolute paths
|
|
604
680
|
|
|
681
|
+
## Development
|
|
682
|
+
|
|
683
|
+
### Running tests
|
|
684
|
+
|
|
685
|
+
```bash
|
|
686
|
+
# Unit tests (no device needed)
|
|
687
|
+
python -m unittest discover tests/ -v
|
|
688
|
+
|
|
689
|
+
# Read-only integration tests (safe on production device)
|
|
690
|
+
MPYTOOL_TEST_PORT=/dev/ttyACM0 python -m unittest tests.test_integration -v
|
|
691
|
+
|
|
692
|
+
# All integration tests (dedicated test device)
|
|
693
|
+
MPYTOOL_TEST_PORT_RW=/dev/ttyACM0 python -m unittest tests.test_integration -v
|
|
694
|
+
|
|
695
|
+
# CLI tests (no device needed for basic tests)
|
|
696
|
+
python -m unittest tests.test_cli -v
|
|
697
|
+
|
|
698
|
+
# All CLI tests with device
|
|
699
|
+
MPYTOOL_TEST_PORT_RW=/dev/ttyACM0 python -m unittest tests.test_cli -v
|
|
700
|
+
```
|
|
701
|
+
|
|
702
|
+
Test categories:
|
|
703
|
+
- **Unit tests** (`test_*.py` except `test_integration.py`, `test_cli.py`) - no device needed
|
|
704
|
+
- **Read-only tests** (`MPYTOOL_TEST_PORT`) - safe on any device, no filesystem changes
|
|
705
|
+
- **All tests** (`MPYTOOL_TEST_PORT_RW`) - includes write and flash operations, use dedicated test device
|
|
706
|
+
|
|
707
|
+
### Install from source
|
|
708
|
+
|
|
709
|
+
```bash
|
|
710
|
+
pip install -e .
|
|
711
|
+
```
|
|
712
|
+
|
|
605
713
|
## Requirements
|
|
606
714
|
|
|
607
715
|
Working only with MicroPython boards, not with CircuitPython
|
|
@@ -216,10 +216,7 @@ class CopyCommand:
|
|
|
216
216
|
else:
|
|
217
217
|
self._progress_src = self._format_local_path(src)
|
|
218
218
|
if is_dst_remote:
|
|
219
|
-
|
|
220
|
-
self._progress_dst = ':' + dst
|
|
221
|
-
else:
|
|
222
|
-
self._progress_dst = ':/' + dst
|
|
219
|
+
self._progress_dst = ':' + dst
|
|
223
220
|
else:
|
|
224
221
|
self._progress_dst = self._format_local_path(dst)
|
|
225
222
|
if len(self._progress_dst) > self._progress_max_dst_len:
|