micropython-stubber 1.17.4__py3-none-any.whl → 1.17.6__py3-none-any.whl

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.
Files changed (36) hide show
  1. {micropython_stubber-1.17.4.dist-info → micropython_stubber-1.17.6.dist-info}/METADATA +1 -1
  2. {micropython_stubber-1.17.4.dist-info → micropython_stubber-1.17.6.dist-info}/RECORD +34 -34
  3. mpflash/README.md +149 -0
  4. {mptool/mptool → mpflash/mpflash}/cli_group.py +4 -3
  5. {mptool/mptool → mpflash/mpflash}/cli_main.py +4 -4
  6. {mptool/mptool → mpflash/mpflash}/common.py +4 -5
  7. {mptool/mptool → mpflash/mpflash}/config.py +1 -1
  8. {mptool/mptool → mpflash/mpflash}/downloader.py +14 -36
  9. {mptool/mptool → mpflash/mpflash}/flash_uf2.py +3 -9
  10. {mptool/mptool → mpflash/mpflash}/flash_uf2_linux.py +12 -6
  11. {mptool/mptool → mpflash/mpflash}/flasher.py +14 -25
  12. {mptool/mptool → mpflash/mpflash}/list.py +1 -5
  13. {mptool → mpflash}/poetry.lock +27 -30
  14. mpflash/pyproject.toml +41 -0
  15. stubber/__init__.py +1 -2
  16. stubber/board/createstubs.py +3 -1
  17. stubber/board/createstubs_db.py +4 -2
  18. stubber/board/createstubs_db_min.py +34 -33
  19. stubber/board/createstubs_db_mpy.mpy +0 -0
  20. stubber/board/createstubs_mem.py +4 -2
  21. stubber/board/createstubs_mem_min.py +34 -33
  22. stubber/board/createstubs_mem_mpy.mpy +0 -0
  23. stubber/board/createstubs_min.py +34 -33
  24. stubber/board/createstubs_mpy.mpy +0 -0
  25. stubber/bulk/runner.py +3 -1
  26. mptool/README.md +0 -10
  27. mptool/pyproject.toml +0 -34
  28. {micropython_stubber-1.17.4.dist-info → micropython_stubber-1.17.6.dist-info}/LICENSE +0 -0
  29. {micropython_stubber-1.17.4.dist-info → micropython_stubber-1.17.6.dist-info}/WHEEL +0 -0
  30. {micropython_stubber-1.17.4.dist-info → micropython_stubber-1.17.6.dist-info}/entry_points.txt +0 -0
  31. {mptool/mptool → mpflash/mpflash}/__init__.py +0 -0
  32. {mptool/mptool → mpflash/mpflash}/flash_esp.py +0 -0
  33. {mptool/mptool → mpflash/mpflash}/flash_stm32.py +0 -0
  34. {mptool/mptool → mpflash/mpflash}/flash_uf2_windows.py +0 -0
  35. {mptool/mptool → mpflash/mpflash}/logger.py +0 -0
  36. {mptool/mptool → mpflash/mpflash}/uf2_boardid.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: micropython-stubber
3
- Version: 1.17.4
3
+ Version: 1.17.6
4
4
  Summary: Tooling to create and maintain stubs for MicroPython
5
5
  Home-page: https://github.com/Josverl/micropython-stubber#readme
6
6
  License: MIT
@@ -1,37 +1,37 @@
1
- mptool/mptool/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- mptool/mptool/cli_group.py,sha256=nxgH-gZ7sdxdppOHz6fnzB7I9Lu9ubz6r3QfFkrhSsc,1223
3
- mptool/mptool/cli_main.py,sha256=Sr7cdTOwqfi-nrr77NRF6zzIOS_qSDNbECF8_6_Vq64,495
4
- mptool/mptool/common.py,sha256=bW1_JY5904cm6luUlMQmzgYXk7ukrDyMaxwovOyfHes,3875
5
- mptool/mptool/config.py,sha256=n3v-w6VKvcUqpRQAfMAdrk_3-_XRw8fRIFaD379dN9w,159
6
- mptool/mptool/downloader.py,sha256=OsOTNjv-91RQc2quD8ptUzI1-pJhHekE8jARdg-1rhk,9961
7
- mptool/mptool/flash_esp.py,sha256=XffVg1BKzaQo4pzSJdUoHmHa7h4s4gBlNQR50ahGJ1E,2301
8
- mptool/mptool/flash_stm32.py,sha256=Pn1y9rKw48D0khucT8yU3NjFkHQ9YYTvwco9ir4MmpQ,3742
9
- mptool/mptool/flash_uf2.py,sha256=I795z12x8_KkiCg0WUirXabkc1vj7zNFcPvxWO8nEdo,2072
10
- mptool/mptool/flash_uf2_linux.py,sha256=NlnFN67qmUHw4GKOSay87I4H30ipOlrdHkFTF7MLwPc,3841
11
- mptool/mptool/flash_uf2_windows.py,sha256=AiFg5jrSyEMX2QxC2sgfn8GekKBw-fPkIi8emlU7Z7o,711
12
- mptool/mptool/flasher.py,sha256=_N-CYZZZ401kxZ45CDgl1XDj3lqdMPHjhpbn82ow2Kc,9575
13
- mptool/mptool/list.py,sha256=shFNDyEnmqqDjiJ4WSpJLTkDO_6H3fvYBeJKzfGFJMw,2004
14
- mptool/mptool/logger.py,sha256=FvGQSR2l4O9nmJV0rKbyoeJDd7fbY2vKQTmPEED0h6s,1048
15
- mptool/mptool/uf2_boardid.py,sha256=WZKucGu_hJ8ymb236uuZbiR6pD6AA_l4LA-7LwtQhq8,414
16
- mptool/poetry.lock,sha256=BGPosn3e__H3c0QlYw_9c9EFfHPeMY6OLasgNAmhm5g,137373
17
- mptool/pyproject.toml,sha256=GFBnLevRmBiahnqOk_RdBVElJLOoTpdk5WQsDX_lxDA,910
18
- mptool/README.md,sha256=y08mpllwvpZk29LDylbrPoiMBSVRifLVJetLHTFoaOw,287
19
- stubber/__init__.py,sha256=aYwROv-hMrVTvKEq1i44H3geRl57NBjJeAQq7GhR2lM,51
1
+ mpflash/mpflash/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ mpflash/mpflash/cli_group.py,sha256=oWgZlUoXY_Wc9-XMXxuxH3F0TevYNafsFWpRtT_WiiU,1228
3
+ mpflash/mpflash/cli_main.py,sha256=nLFfR-ti_stLVvgwDRsNXgaQ43gQVZUOz_xvRERPuy0,494
4
+ mpflash/mpflash/common.py,sha256=RBNfbojPKLK3_cxLFIvtHWy8UZUbBxN0ogBN0nliVR4,3896
5
+ mpflash/mpflash/config.py,sha256=R_sYZ_UwzIc9H2vhwIU5RSDhpcV3fHIX83FEURWOd5E,160
6
+ mpflash/mpflash/downloader.py,sha256=QVtgocj4b-c9ZunzEZnsyhEZu_Lbk8Hk-43qWBMJ0AI,9783
7
+ mpflash/mpflash/flash_esp.py,sha256=XffVg1BKzaQo4pzSJdUoHmHa7h4s4gBlNQR50ahGJ1E,2301
8
+ mpflash/mpflash/flash_stm32.py,sha256=Pn1y9rKw48D0khucT8yU3NjFkHQ9YYTvwco9ir4MmpQ,3742
9
+ mpflash/mpflash/flash_uf2.py,sha256=8rZRqdi3Rtp8UsHxKgmoMfZ1yBXZbMFXcOeyVVMmX5w,2029
10
+ mpflash/mpflash/flash_uf2_linux.py,sha256=wXtpqFan6x5k8h2bwwLqwY-LKbpyTg7n2SbD4eb6yH0,4012
11
+ mpflash/mpflash/flash_uf2_windows.py,sha256=AiFg5jrSyEMX2QxC2sgfn8GekKBw-fPkIi8emlU7Z7o,711
12
+ mpflash/mpflash/flasher.py,sha256=J7-bsrfQ0MPEKrnUx47q0OqAS61roLBaETu4nv4MfMU,9400
13
+ mpflash/mpflash/list.py,sha256=7GpZEK7fh6GCzgUdRLHGp8FMEeCbLstV-2u3ohaRYsc,1970
14
+ mpflash/mpflash/logger.py,sha256=FvGQSR2l4O9nmJV0rKbyoeJDd7fbY2vKQTmPEED0h6s,1048
15
+ mpflash/mpflash/uf2_boardid.py,sha256=WZKucGu_hJ8ymb236uuZbiR6pD6AA_l4LA-7LwtQhq8,414
16
+ mpflash/poetry.lock,sha256=1Gf00ycWFfkHFFmLFDnL8ov7GhZPz0qYv-k2S91s-xo,137771
17
+ mpflash/pyproject.toml,sha256=vffY5dhFWQLUllZl_-f5YFfSsmYwvBN8DakysierFOA,1247
18
+ mpflash/README.md,sha256=B25tOMF5eyZ3ych_6pfTWRc6cJxwNPXbw7F2QMfJt8A,11455
19
+ stubber/__init__.py,sha256=b_G4a0TzIG3P--Gsh1qzZaXiera0wZdKQDeZvPTSECM,49
20
20
  stubber/basicgit.py,sha256=5y7eIxmZXfGHwgGrdHtFWTB-tYdgAc7A-0b299wHMYc,9543
21
21
  stubber/board/board_info.csv,sha256=K2VSmfR013fN-oJWkQUmiQ19w09dVwJHDquPy6QmMhY,8627
22
22
  stubber/board/boot.py,sha256=XjWlKErU5nI1HJSugXIP_3hlwgRQboE6sJrpcbSygnk,1120
23
- stubber/board/createstubs.py,sha256=xEnuXXGN1_siM94csiGhUaaJFUYS7l2LCbEvWwW3Op4,32416
24
- stubber/board/createstubs_db.py,sha256=JmDzwne4QUzoWRPy3Awi3AcB3O8WIJnigQ8nAQDmILw,30154
25
- stubber/board/createstubs_db_min.py,sha256=TxMRP4g45nkIAzVkeC7Axr2vvsXZpNkm1gkJtryiYDY,11386
26
- stubber/board/createstubs_db_mpy.mpy,sha256=4gYaYGiHUk3PpQ_a5w8-2dkczQVOhz25A2Wy0vFavGM,9472
23
+ stubber/board/createstubs.py,sha256=4yD2Ixt-E2fUS2Rq3zBrcFKYNr_avNg0pBWQP4HrWgk,32546
24
+ stubber/board/createstubs_db.py,sha256=pbfa7tNxs0GtjaknCCDPmDqNpukw5DKqqd3UlJNiW2E,30284
25
+ stubber/board/createstubs_db_min.py,sha256=FxhpNl8iMpH8JNXy8f6i0Ijk_e6rlGiHRv5gVK5HuYM,11424
26
+ stubber/board/createstubs_db_mpy.mpy,sha256=tedfLsrbARO2mqJrZ-8565wMg4VMq88yB-S_f4xjt0I,9509
27
27
  stubber/board/createstubs_lvgl.py,sha256=CTe7eq1ACRK_JJxavaqDD8znn29nSWJiHHTZ_ps6EhM,27217
28
28
  stubber/board/createstubs_lvgl_min.py,sha256=jLkWYmeboI2A8feMC7pT7cYWttLejQTuX7WAEZCylhw,27207
29
29
  stubber/board/createstubs_lvgl_mpy.mpy,sha256=ex-nlq2V5e8anQBJvRWEEc-FzU7nlwg5NSrZ8vOadIA,9267
30
- stubber/board/createstubs_mem.py,sha256=HUh8IWVcjpBqlJUgSZy7SWZY3t1zmpvzlpo_8qz-VqA,28488
31
- stubber/board/createstubs_mem_min.py,sha256=4HPWe7hLLMKGNYl970499NTTD4nClF0_koEkY_mtypI,10932
32
- stubber/board/createstubs_mem_mpy.mpy,sha256=G7WqJnAKjmwnUp-ASoV-TxHqIBid2LJE4ZHoINg3FME,9054
33
- stubber/board/createstubs_min.py,sha256=dxGgdbLpwnA4gJ576x3OkbznREZXcMf6b2w7fuTTNuo,13471
34
- stubber/board/createstubs_mpy.mpy,sha256=SVsdlZw0YSYF-RuBQ9OSTD0I3PXVSpQPY8PowDFuv_E,12156
30
+ stubber/board/createstubs_mem.py,sha256=H8RV8p_tI8u2wsxbv4lPUQ-6e5xm0G2fL48s09rk1OY,28618
31
+ stubber/board/createstubs_mem_min.py,sha256=aJGZFnYhz3nF7R8OZDydOBs1y1RorLDpV6UYpo3ykSg,10970
32
+ stubber/board/createstubs_mem_mpy.mpy,sha256=SJow8erMqxCCDTkrmy5_O1S-iQy5uXyTosYGEkSpTY8,9091
33
+ stubber/board/createstubs_min.py,sha256=9s0KTIXVwzD386ECOvVd1MW04bztv1XZd1WbsDtPErs,13509
34
+ stubber/board/createstubs_mpy.mpy,sha256=YBDgMGamFVTq6HvTsQkAWBi7TxvC0oBEsqVL7IWbB2o,12193
35
35
  stubber/board/fw_info.py,sha256=6AQbN3jtQgllqWQYl4e-63KeEtV08EXk8_JnM6XBkvo,4554
36
36
  stubber/board/info.py,sha256=b7SOPZHVsVhaayKCwVkFZlYu0BW-UFI7LuG1Eop9480,5629
37
37
  stubber/board/main.py,sha256=f6V3tdt6sPZVLuwemT-NLuK9GySfW2c2J6PJMOOWQQw,413
@@ -40,7 +40,7 @@ stubber/board/pyrightconfig.json,sha256=6oHS4aDOfwKBAFeUPsCGJzEXpUgBZsPaF0M4P-N2
40
40
  stubber/bulk/board_id.py,sha256=R37zhRpg9kj3CqDJvPacQdbLq4d9k-Du1e7VUDWrzkI,1531
41
41
  stubber/bulk/mcu_stubber.py,sha256=NvJ8Q8nw09EfUsRg58FOGLldvb3lVIqQ1CHnpIIyeSk,16287
42
42
  stubber/bulk/mpremoteboard.py,sha256=YtaCZBCeS1ZBZrLGI7cVWuM0-0Fyc-hSpxLWofmo0qA,4843
43
- stubber/bulk/runner.py,sha256=r6b5V6U6LvYbrHH2L8zWwsaCqoTvgVTdU4w83CUH79Y,4070
43
+ stubber/bulk/runner.py,sha256=AQUu8Rhj2jN5-R8F7zHi8pOCv6Z3HE0E0-KIed7QDx4,4159
44
44
  stubber/codemod/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
45
45
  stubber/codemod/_partials/__init__.py,sha256=4v1lkgSBzFw08gxwujh5sivpbJbYqg5lZeRzgyvN4TE,1561
46
46
  stubber/codemod/_partials/db_main.py,sha256=APeyLDuAc-FNXRQ7ECFVqVPLfOLVyAoLuE83e2Sfg1E,4183
@@ -125,8 +125,8 @@ stubber/utils/stubmaker.py,sha256=qld_Wfm9f4EuzedXlX1Ky0i0BJdR75oOOTha13_ekz0,52
125
125
  stubber/utils/typed_config_toml.py,sha256=ikifCIZGNhS_uqsfp6IwIpxdtZqbLtywprjWG_Q0y8o,2629
126
126
  stubber/utils/versions.py,sha256=VvADhHG3ZEu5z1mm927Aj18PO1krFvxVXxxwdecRPlY,3756
127
127
  stubber/variants.py,sha256=-o4TgotbKaCcYBdXkutPaBSR1JdxWmOAiuNT1UlahYc,3784
128
- micropython_stubber-1.17.4.dist-info/entry_points.txt,sha256=NQi_M36fgq5k6giSuASas3LrpF6CVdkzfvJC0ja73_g,55
129
- micropython_stubber-1.17.4.dist-info/LICENSE,sha256=Fx9qrL45ayRXgH6QzttboqZEjKXms0w1t_b_nkOqYCU,1572
130
- micropython_stubber-1.17.4.dist-info/METADATA,sha256=JSa8pVPDEkS7a85F2uwzwhFRBPBrRn7riMXgzjN_zFU,19029
131
- micropython_stubber-1.17.4.dist-info/WHEEL,sha256=d2fvjOD7sXsVzChCqf0Ty0JbHKBaLYwDbGQDwQTnJ50,88
132
- micropython_stubber-1.17.4.dist-info/RECORD,,
128
+ micropython_stubber-1.17.6.dist-info/entry_points.txt,sha256=NQi_M36fgq5k6giSuASas3LrpF6CVdkzfvJC0ja73_g,55
129
+ micropython_stubber-1.17.6.dist-info/LICENSE,sha256=Fx9qrL45ayRXgH6QzttboqZEjKXms0w1t_b_nkOqYCU,1572
130
+ micropython_stubber-1.17.6.dist-info/METADATA,sha256=vXkIJk9X8j3kkA6jrJzRYWXYeGXoASOg8710O_qwL8s,19029
131
+ micropython_stubber-1.17.6.dist-info/WHEEL,sha256=d2fvjOD7sXsVzChCqf0Ty0JbHKBaLYwDbGQDwQTnJ50,88
132
+ micropython_stubber-1.17.6.dist-info/RECORD,,
mpflash/README.md ADDED
@@ -0,0 +1,149 @@
1
+ # mpflash
2
+ mpflash is a command-line tool for working with MicroPython firmware. It provides various features to help you develop, build, and manage your MicroPython projects.
3
+
4
+ This tool was created to be used in a CI/CD pipeline to automate the process of downloading and flashing MicroPython firmware to multiple boards, but it can also be used for manual flashing and development.
5
+
6
+ mpflash has been tested on Windows x64, Linux X64 and ARM64, but not (yet) macOS.
7
+
8
+ ## Features
9
+ 1. List the connected boards including their firmware details, in a tabular or json format
10
+ 2. Download MicroPython firmware for specific boards and versions.
11
+ 3. Flash one or all connected MicroPython boards with a specific firmware or version.
12
+ Tested ports: rp2, samd, esp32, esp32s3, esp8266 and stm32 (requires cubeprogrammer)
13
+
14
+ ## Installation
15
+ To install mpflash, you can use pip: `pip install mpflash`
16
+
17
+ ## How to use
18
+ You can list the connected boards using the following command:
19
+ ```bash
20
+ $ mpflash list
21
+ D:\MyPython\micropython-stubber> mpflash list
22
+ Getting board info ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:02
23
+ Connected boards
24
+ ┏━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━┓
25
+ ┃ Serial ┃ Family ┃ Port ┃ Board ┃ CPU ┃ Version ┃ build ┃
26
+ ┡━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━┩
27
+ │ COM11 │ micropython │ rp2 │ RPI_PICO_W │ RP2040 │ 1.20.0 │ │
28
+ │ COM12 │ micropython │ esp8266 │ ESP8266_GENERIC │ ESP8266 │ 1.22.2 │ │
29
+ │ COM18 │ micropython │ rp2 │ RPI_PICO_W │ RP2040 │ 1.23.0-preview │ 155 │
30
+ │ COM3 │ micropython │ samd │ SEEED_WIO_TERMINAL │ SAMD51P19A │ 1.23.0-preview │ 155 │
31
+ │ COM5 │ micropython │ stm32 │ PYBV11 │ STM32F405RG │ 1.23.0-preview │ 166 │
32
+ │ COM8 │ micropython │ esp32 │ ESP32_GENERIC_S3 │ ESP32S3 │ 1.23.0-preview │ 155 │
33
+ └────────┴─────────────┴─────────┴────────────────────┴─────────────┴────────────────┴───────┘
34
+ ```
35
+
36
+ Suppose you want to download the MicroPython firmware for some boards, you can use the following command:
37
+
38
+ ```bash
39
+ # download the firmware
40
+ $ mpflash download --board ESP8266_GENERIC --board SEEED_WIO_TERMINAL
41
+ ```
42
+ This will download the latest stable version of the MicroPython firmware for the boards and save it in the `firmware` directory.
43
+ The stable version (default) is determined based on the most recent published release,
44
+ other optionse are `--version preview` and `--version x.y.z` to download the latest preview or version x.y.z respectively.
45
+
46
+ by default the firmware will be downloaded to Downloads in a `firmware` folder in your, but you can specify a different directory using the `--dir` option.
47
+
48
+ ```bash
49
+ The directory structure will be something like this:
50
+ ```
51
+ Downloads/firmware
52
+ | firmware.jsonl
53
+ +---esp8266
54
+ | ESP8266_GENERIC-FLASH_1M-v1.22.2.bin
55
+ | ESP8266_GENERIC-FLASH_512K-v1.22.2.bin
56
+ | ESP8266_GENERIC-OTA-v1.22.2.bin
57
+ | ESP8266_GENERIC-v1.22.2.bin
58
+ \---samd
59
+ SEEED_WIO_TERMINAL-v1.22.2.uf2
60
+ ```
61
+ You can then flash the firmware to the board using the following command: `mpflash flash`
62
+ This will (try to) autodetect the connected boards, and determine the correct firmware to flash to each board.
63
+
64
+ ```bash
65
+ > mpflash flash
66
+ 22:15:55 | ℹ️ - Using latest stable version: v1.22.2
67
+ Connected boards
68
+ ┏━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━┓
69
+ ┃ Serial ┃ Family ┃ Port ┃ Board ┃ CPU ┃ Version ┃ build ┃
70
+ ┡━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━┩
71
+ │ COM11 │ micropython │ rp2 │ RPI_PICO_W │ RP2040 │ 1.20.0 │ │
72
+ │ COM12 │ micropython │ esp8266 │ ESP8266_GENERIC │ ESP8266 │ 1.22.2 │ │
73
+ │ COM18 │ micropython │ rp2 │ RPI_PICO_W │ RP2040 │ 1.23.0-preview │ 155 │
74
+ │ COM3 │ micropython │ samd │ SEEED_WIO_TERMINAL │ SAMD51P19A │ 1.23.0-preview │ 155 │
75
+ │ COM5 │ micropython │ stm32 │ PYBV11 │ STM32F405RG │ 1.23.0-preview │ 166 │
76
+ │ COM8 │ micropython │ esp32 │ ESP32_GENERIC_S3 │ ESP32S3 │ 1.23.0-preview │ 155 │
77
+ └────────┴─────────────┴─────────┴────────────────────┴─────────────┴────────────────┴───────┘
78
+ 22:15:58 | ℹ️ - Found v1.22.2 firmware rp2\RPI_PICO_W-v1.22.2.uf2 for RPI_PICO_W on COM11.
79
+ 22:15:58 | ℹ️ - Found v1.22.2 firmware esp8266\ESP8266_GENERIC-v1.22.2.bin for ESP8266_GENERIC on COM12.
80
+ 22:15:58 | ℹ️ - Found v1.22.2 firmware rp2\RPI_PICO_W-v1.22.2.uf2 for RPI_PICO_W on COM18.
81
+ 22:15:58 | ℹ️ - Found v1.22.2 firmware samd\SEEED_WIO_TERMINAL-v1.22.2.uf2 for SEEED_WIO_TERMINAL on COM3.
82
+ 22:15:58 | ⚠️ - Trying to find a firmware for the board PYBV11
83
+ 22:15:58 | ❌ - No v1.22.2 firmware found for PYBV11 on COM5.
84
+ 22:15:58 | ⚠️ - Trying to find a firmware for the board ESP32-GENERIC-S3
85
+ 22:15:58 | ❌ - No v1.22.2 firmware found for ESP32_GENERIC_S3 on COM8.
86
+ 22:15:58 | ℹ️ - Updating RPI_PICO_W on COM11 to 1.22.2
87
+ 22:15:58 | ℹ️ - Erasing not yet implemented for UF2 flashing.
88
+ 22:15:58 | ℹ️ - Entering UF2 bootloader on RPI_PICO_W on COM11
89
+ 22:15:58 | ℹ️ - Waiting for mcu to mount as a drive : 10 seconds left
90
+ 22:15:59 | ℹ️ - Waiting for mcu to mount as a drive : 9 seconds left
91
+ 22:16:00 | ℹ️ - Board is in bootloader mode
92
+ 22:16:00 | ℹ️ - Copying firmware\rp2\RPI_PICO_W-v1.22.2.uf2 to F:
93
+ 22:16:13 | ✅ - Done copying, resetting the board and wait for it to restart
94
+ 22:16:23 | ℹ️ - Updating ESP8266_GENERIC on COM12 to 1.22.2
95
+ 22:16:23 | ℹ️ - Flashing firmware\esp8266\ESP8266_GENERIC-v1.22.2.bin on ESP8266_GENERIC on COM12
96
+ 22:16:23 | ℹ️ - Running esptool --chip ESP8266 --port COM12 erase_flash
97
+ esptool.py v4.7.0
98
+ Serial port COM12
99
+ Connecting....
100
+ ...
101
+ Chip erase completed successfully in 6.5s
102
+ Hard resetting via RTS pin...
103
+ 22:16:31 | ℹ️ - Running esptool --chip ESP8266 --port COM12 -b 460800 write_flash --flash_size=detect 0x0 firmware\esp8266\ESP8266_GENERIC-v1.22.2.bin
104
+ esptool.py v4.7.0
105
+ Serial port COM12
106
+ Connecting....
107
+ ...
108
+ Leaving...
109
+ Hard resetting via RTS pin...
110
+ 22:16:43 | ℹ️ - Done flashing, resetting the board and wait for it to restart
111
+ 22:16:49 | ✅ - Flashed 1.22.2 to ESP8266_GENERIC on COM12 done
112
+ 22:16:49 | ℹ️ - Updating RPI_PICO_W on COM18 to 1.22.2
113
+ 22:16:49 | ℹ️ - Erasing not yet implemented for UF2 flashing.
114
+ 22:16:49 | ℹ️ - Entering UF2 bootloader on RPI_PICO_W on COM18
115
+ 22:16:49 | ℹ️ - Waiting for mcu to mount as a drive : 10 seconds left
116
+ 22:16:50 | ℹ️ - Waiting for mcu to mount as a drive : 9 seconds left
117
+ 22:16:51 | ℹ️ - Board is in bootloader mode
118
+ 22:16:51 | ℹ️ - Copying firmware\rp2\RPI_PICO_W-v1.22.2.uf2 to F:[/bold]
119
+ 22:17:02 | ✅ - Done copying, resetting the board and wait for it to restart
120
+ 22:17:12 | ℹ️ - Updating SEEED_WIO_TERMINAL on COM3 to 1.22.2
121
+ 22:17:12 | ℹ️ - Erasing not yet implemented for UF2 flashing.
122
+ 22:17:12 | ℹ️ - Entering UF2 bootloader on SEEED_WIO_TERMINAL on COM3
123
+ 22:17:12 | ℹ️ - Waiting for mcu to mount as a drive : 10 seconds left
124
+ 22:17:13 | ℹ️ - Waiting for mcu to mount as a drive : 9 seconds left
125
+ 22:17:14 | ℹ️ - Board is in bootloader mode
126
+ 22:17:14 | ℹ️ - Copying firmware\samd\SEEED_WIO_TERMINAL-v1.22.2.uf2 to F:[/bold]
127
+ 22:17:17 | ✅ - Done copying, resetting the board and wait for it to restart
128
+ 22:17:27 | ℹ️ - Flashed 4 boards
129
+ Connected boards after flashing
130
+ ┏━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━┓
131
+ ┃ Serial ┃ Family ┃ Port ┃ Board ┃ CPU ┃ Version ┃ build ┃
132
+ ┡━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━┩
133
+ │ COM11 │ micropython │ rp2 │ RPI_PICO_W │ RP2040 │ 1.22.2 │ │
134
+ │ COM12 │ micropython │ esp8266 │ ESP8266_GENERIC │ ESP8266 │ 1.22.2 │ │
135
+ │ COM18 │ micropython │ rp2 │ RPI_PICO_W │ RP2040 │ 1.22.2 │ │
136
+ │ COM3 │ micropython │ samd │ SEEED_WIO_TERMINAL │ SAMD51P19A │ 1.22.2 │ │
137
+ │ COM5 │ micropython │ stm32 │ PYBV11 │ STM32F405RG │ 1.23.0-preview │ 166 │
138
+ │ COM8 │ micropython │ esp32 │ ESP32_GENERIC_S3 │ ESP32S3 │ 1.23.0-preview │ 155 │
139
+ └────────┴─────────────┴─────────┴────────────────────┴─────────────┴────────────────┴───────┘
140
+ ```
141
+ Note that if no matching firmware can be found for a board, it will be skipped.
142
+ (For example, the PYBV11 and ESP32_GENERIC_S3 boards in the example above.)
143
+
144
+ ## Issues and bug reports
145
+ mpflash is currently co-located in the [micropython-stubber](https://github.com/Josverl/micropython-stubber) repository.
146
+ Please report any issues or bugs in the [issue tracker](https://github.com/Josverl/micropython-stubber/issues) with '[mpflash]' in the subject.
147
+
148
+ ## License
149
+ mpflash is licensed under the MIT license. See the LICENSE file for more details.
@@ -4,6 +4,7 @@ Additional comands are added in the submodules.
4
4
  """
5
5
 
6
6
  from typing import List
7
+
7
8
  import rich_click as click
8
9
 
9
10
  from .config import config
@@ -39,16 +40,16 @@ def cb_ignore(ctx, param, value):
39
40
  "--ignore",
40
41
  "-i",
41
42
  is_eager=True,
42
- help="Serial port(s) to ignore. Defaults to MPTOOL_IGNORE.",
43
+ help="Serial port(s) to ignore. Defaults to MPFLASH_IGNORE.",
43
44
  callback=cb_ignore,
44
45
  multiple=True,
45
46
  default=[],
46
- envvar="MPTOOL_IGNORE",
47
+ envvar="MPFLASH_IGNORE",
47
48
  show_default=True,
48
49
  metavar="SERIALPORT",
49
50
  )
50
51
  def cli(verbose: bool, ignore: List[str], **kwargs):
51
- """mptool - MicroPython Tool.
52
+ """mpflash - MicroPython Tool.
52
53
 
53
54
  A CLI to download and flash MicroPython firmware to different ports and boards.
54
55
  """
@@ -1,4 +1,4 @@
1
- """mptool is a CLI to download and flash MicroPython firmware to various boards."""
1
+ """mpflash is a CLI to download and flash MicroPython firmware to various boards."""
2
2
 
3
3
  import rich_click as click
4
4
 
@@ -10,12 +10,12 @@ from .list import list_boards
10
10
  # from loguru import logger as log
11
11
 
12
12
 
13
- def mptool():
13
+ def mpflash():
14
14
  # cli.add_command(flash_board)
15
15
  # cli.add_command(list_boards)
16
16
  # cli.add_command(download)
17
- cli() # auto_envvar_prefix='MPTOOL')
17
+ cli(auto_envvar_prefix="MPFLASH")
18
18
 
19
19
 
20
20
  if __name__ == "__main__":
21
- mptool()
21
+ mpflash()
@@ -1,6 +1,7 @@
1
1
  from pathlib import Path
2
2
  from typing import Dict, Union
3
3
 
4
+ import platformdirs
4
5
  from github import Github
5
6
  from loguru import logger as log
6
7
  from packaging.version import parse
@@ -12,11 +13,11 @@ PORT_FWTYPES = {
12
13
  "rp2": ".uf2",
13
14
  "samd": ".uf2",
14
15
  "mimxrt": ".hex",
15
- "nrf": ".hex",
16
+ "nrf": ".uf2",
16
17
  "renesas-ra": ".hex",
17
18
  }
18
19
 
19
- DEFAULT_FW_PATH = Path.cwd() / "firmware"
20
+ DEFAULT_FW_PATH = platformdirs.user_downloads_path() / "firmware"
20
21
  # DEFAULT_FW_PATH = Path.home() / "mp_firmware"
21
22
 
22
23
  FWInfo = Dict[str, Union[str, bool]]
@@ -87,9 +88,7 @@ def micropython_versions(minver: str = "v1.9.2"):
87
88
  g = Github()
88
89
  _ = 1 / 0
89
90
  repo = g.get_repo("micropython/micropython")
90
- versions = [
91
- tag.name for tag in repo.get_tags() if parse(tag.name) >= parse(minver)
92
- ]
91
+ versions = [tag.name for tag in repo.get_tags() if parse(tag.name) >= parse(minver)]
93
92
  except Exception:
94
93
  versions = [
95
94
  "v9.99.9-preview",
@@ -1,4 +1,4 @@
1
- """centralized configuration for mptool"""
1
+ """centralized configuration for mpflash"""
2
2
 
3
3
  from typing import List
4
4
 
@@ -18,7 +18,7 @@ from loguru import logger as log
18
18
  from rich.progress import track
19
19
 
20
20
  from .cli_group import cli
21
- from .common import PORT_FWTYPES, clean_version
21
+ from .common import DEFAULT_FW_PATH, PORT_FWTYPES, clean_version
22
22
 
23
23
  MICROPYTHON_ORG_URL = "https://micropython.org/"
24
24
 
@@ -40,6 +40,7 @@ DEFAULT_BOARDS = [
40
40
  "ARDUINO_NANO_RP2040_CONNECT",
41
41
  "PIMORONI_PICOLIPO_16MB",
42
42
  "SEEED_WIO_TERMINAL",
43
+ "PARTICLE_XENON",
43
44
  ]
44
45
 
45
46
 
@@ -77,9 +78,7 @@ def firmware_list(board_url: str, base_url: str, ext: str) -> List[str]:
77
78
  tags = soup.findAll(
78
79
  "a",
79
80
  recursive=True,
80
- attrs={
81
- "href": re.compile(r"^/resources/firmware/.*\." + ext.lstrip(".") + "$")
82
- },
81
+ attrs={"href": re.compile(r"^/resources/firmware/.*\." + ext.lstrip(".") + "$")},
83
82
  )
84
83
  if "?" in base_url:
85
84
  base_url = base_url.split("?")[0]
@@ -94,9 +93,7 @@ FirmwareInfo = Dict[str, str]
94
93
  # boards we are interested in ( this avoids getting a lot of boards we don't care about)
95
94
  # The first run takes ~60 seconds to run for 4 ports , all boards
96
95
  # so it makes sense to cache the results and skip boards as soon as possible
97
- def get_boards(
98
- fw_types: Dict[str, str], board_list: List[str], clean: bool
99
- ) -> List[FirmwareInfo]:
96
+ def get_boards(fw_types: Dict[str, str], board_list: List[str], clean: bool) -> List[FirmwareInfo]:
100
97
  board_urls: List[FirmwareInfo] = []
101
98
  for port in fw_types:
102
99
  download_page_url = f"{MICROPYTHON_ORG_URL}download/?port={port}"
@@ -107,9 +104,7 @@ def get_boards(
107
104
  for board in _urls:
108
105
  board["port"] = port
109
106
 
110
- for board in track(
111
- _urls, description="Checking download pages", transient=True
112
- ):
107
+ for board in track(_urls, description=f"Checking {port} download pages", transient=True):
113
108
  # add a board to the list for each firmware found
114
109
  firmwares = firmware_list(board["url"], MICROPYTHON_ORG_URL, fw_types[port])
115
110
  for _url in firmwares:
@@ -130,11 +125,7 @@ def get_boards(
130
125
  # remove hash from firmware name
131
126
  fname = re.sub(RE_HASH, ".", fname)
132
127
  board["filename"] = fname
133
- board["variant"] = (
134
- board["filename"].split("-v")[0]
135
- if "-v" in board["filename"]
136
- else ""
137
- )
128
+ board["variant"] = board["filename"].split("-v")[0] if "-v" in board["filename"] else ""
138
129
  board_urls.append(board.copy())
139
130
  return board_urls
140
131
 
@@ -171,9 +162,7 @@ def download_firmwares(
171
162
 
172
163
  firmware_folder.mkdir(exist_ok=True)
173
164
 
174
- with open(
175
- firmware_folder / "firmware.jsonl", "a", encoding="utf-8", buffering=1
176
- ) as f_jsonl:
165
+ with open(firmware_folder / "firmware.jsonl", "a", encoding="utf-8", buffering=1) as f_jsonl:
177
166
  for board in unique_boards:
178
167
  filename = firmware_folder / board["port"] / board["filename"]
179
168
  filename.parent.mkdir(exist_ok=True)
@@ -197,21 +186,16 @@ def download_firmwares(
197
186
  log.info(f"Downloaded {downloaded} firmwares, skipped {skipped} existing files.")
198
187
 
199
188
 
200
- def get_firmware_list(
201
- board_list: List[str], version_list: List[str], preview: bool, clean: bool
202
- ):
189
+ def get_firmware_list(board_list: List[str], version_list: List[str], preview: bool, clean: bool):
203
190
  log.trace("Checking MicroPython download pages")
204
191
 
205
- board_urls = sorted(
206
- get_boards(PORT_FWTYPES, board_list, clean), key=key_fw_variant_ver
207
- )
192
+ board_urls = sorted(get_boards(PORT_FWTYPES, board_list, clean), key=key_fw_variant_ver)
208
193
 
209
194
  log.debug(f"Total {len(board_urls)} firmwares")
210
195
  relevant = [
211
196
  board
212
197
  for board in board_urls
213
- if board["board"] in board_list
214
- and (board["version"] in version_list or board["preview"] and preview)
198
+ if board["board"] in board_list and (board["version"] in version_list or board["preview"] and preview)
215
199
  # and b["port"] in ["esp32", "rp2"]
216
200
  ]
217
201
  log.debug(f"Matching firmwares: {len(relevant)}")
@@ -233,7 +217,7 @@ def get_firmware_list(
233
217
  "--destination",
234
218
  "-d",
235
219
  type=click.Path(file_okay=False, dir_okay=True, path_type=Path),
236
- default="./firmware",
220
+ default=DEFAULT_FW_PATH,
237
221
  show_default=True,
238
222
  help="The folder to download the firmware to.",
239
223
  )
@@ -267,19 +251,13 @@ def get_firmware_list(
267
251
  help="""Force download of firmware even if it already exists.""",
268
252
  show_default=True,
269
253
  )
270
- def download(
271
- destination: Path, boards: List[str], versions: List[str], force: bool, clean: bool
272
- ):
254
+ def download(destination: Path, boards: List[str], versions: List[str], force: bool, clean: bool):
273
255
  versions = list(versions)
274
256
  # preview is not a version, it is an option to include preview versions
275
257
  preview = "preview" in versions
276
258
  versions = [v for v in versions if v != "preview"]
277
259
 
278
260
  boards = list(boards) or DEFAULT_BOARDS
279
- versions = [
280
- clean_version(v, drop_v=True) for v in versions
281
- ] # remove leading v from version
261
+ versions = [clean_version(v, drop_v=True) for v in versions] # remove leading v from version
282
262
  destination.mkdir(exist_ok=True)
283
- download_firmwares(
284
- destination, boards, versions, preview=preview, force=force, clean=clean
285
- )
263
+ download_firmwares(destination, boards, versions, preview=preview, force=force, clean=clean)
@@ -17,9 +17,7 @@ from .flash_uf2_linux import dismount_uf2, wait_for_UF2_linux
17
17
  from .flash_uf2_windows import wait_for_UF2_windows
18
18
 
19
19
 
20
- def flash_uf2(
21
- mcu: MPRemoteBoard, fw_file: Path, erase: bool
22
- ) -> Optional[MPRemoteBoard]:
20
+ def flash_uf2(mcu: MPRemoteBoard, fw_file: Path, erase: bool) -> Optional[MPRemoteBoard]:
23
21
  """
24
22
  Flash .UF2 devices via bootloader and filecopy
25
23
  - mpremote bootloader
@@ -49,16 +47,12 @@ def flash_uf2(
49
47
  log.error(f"OS {sys.platform} not supported")
50
48
  return None
51
49
 
52
- if (
53
- not destination
54
- or not destination.exists()
55
- or not (destination / "INFO_UF2.TXT").exists()
56
- ):
50
+ if not destination or not destination.exists() or not (destination / "INFO_UF2.TXT").exists():
57
51
  log.error("Board is not in bootloader mode")
58
52
  return None
59
53
 
60
54
  log.info("Board is in bootloader mode")
61
- log.info(f"Copying {fw_file} to {destination}")
55
+ log.info(f"Copying {fw_file} to {destination}.")
62
56
  shutil.copy(fw_file, destination)
63
57
  log.success("Done copying, resetting the board and wait for it to restart")
64
58
  if sys.platform == "linux":
@@ -1,11 +1,13 @@
1
1
  from __future__ import annotations
2
- from pathlib import Path
2
+
3
3
  import subprocess
4
4
  import sys
5
5
  import time
6
+ from pathlib import Path
7
+ from typing import List
8
+
6
9
  from loguru import logger as log
7
10
 
8
- from typing import List
9
11
  from .uf2_boardid import get_board_id
10
12
 
11
13
  glb_dismount_me: List[UF2Disk] = []
@@ -112,10 +114,14 @@ def wait_for_UF2_linux():
112
114
  for drive in get_uf2_drives():
113
115
  pmount(drive)
114
116
  time.sleep(1)
115
- if Path(drive.mountpoint, "INFO_UF2.TXT").exists():
116
- board_id = get_board_id(Path(drive.mountpoint)) # type: ignore
117
- destination = Path(drive.mountpoint)
118
- break
117
+ try:
118
+ if Path(drive.mountpoint, "INFO_UF2.TXT").exists():
119
+ board_id = get_board_id(Path(drive.mountpoint)) # type: ignore
120
+ destination = Path(drive.mountpoint)
121
+ break
122
+ except PermissionError:
123
+ log.debug(f"Permission error on {drive.mountpoint}")
124
+ continue
119
125
  time.sleep(1)
120
126
  wait -= 1
121
127
  return destination
@@ -104,9 +104,7 @@ def auto_update(conn_boards: List[MPRemoteBoard], target_version: str, fw_folder
104
104
  wl: WorkList = []
105
105
  for mcu in conn_boards:
106
106
  if mcu.family != "micropython":
107
- log.warning(
108
- f"Skipping {mcu.board} on {mcu.serialport} as it is not a micropython board"
109
- )
107
+ log.warning(f"Skipping {mcu.board} on {mcu.serialport} as it is not a micropython board")
110
108
  continue
111
109
  board_firmwares = find_firmware(
112
110
  fw_folder=fw_folder,
@@ -117,19 +115,13 @@ def auto_update(conn_boards: List[MPRemoteBoard], target_version: str, fw_folder
117
115
  )
118
116
 
119
117
  if not board_firmwares:
120
- log.error(
121
- f"No {target_version} firmware found for {mcu.board} on {mcu.serialport}."
122
- )
118
+ log.error(f"No {target_version} firmware found for {mcu.board} on {mcu.serialport}.")
123
119
  continue
124
120
  if len(board_firmwares) > 1:
125
- log.debug(
126
- f"Multiple {target_version} firmwares found for {mcu.board} on {mcu.serialport}."
127
- )
121
+ log.debug(f"Multiple {target_version} firmwares found for {mcu.board} on {mcu.serialport}.")
128
122
  # just use the last firmware
129
123
  fw_info = board_firmwares[-1]
130
- log.info(
131
- f"Found {target_version} firmware {fw_info['filename']} for {mcu.board} on {mcu.serialport}."
132
- )
124
+ log.info(f"Found {target_version} firmware {fw_info['filename']} for {mcu.board} on {mcu.serialport}.")
133
125
  wl.append((mcu, fw_info))
134
126
  return wl
135
127
 
@@ -148,7 +140,7 @@ def auto_update(conn_boards: List[MPRemoteBoard], target_version: str, fw_folder
148
140
  "-f",
149
141
  "fw_folder",
150
142
  type=click.Path(exists=True, file_okay=False, dir_okay=True, path_type=Path),
151
- default="./firmware",
143
+ default=DEFAULT_FW_PATH,
152
144
  show_default=True,
153
145
  help="The folder to retrieve the firmware from.",
154
146
  )
@@ -233,9 +225,7 @@ def flash_board(
233
225
  if serial_port == "auto":
234
226
  # update all connected boards
235
227
  conn_boards = [
236
- MPRemoteBoard(sp)
237
- for sp in MPRemoteBoard.connected_boards()
238
- if sp not in config.ignore_ports
228
+ MPRemoteBoard(sp) for sp in MPRemoteBoard.connected_boards() if sp not in config.ignore_ports
239
229
  ]
240
230
  else:
241
231
  # just this serial port
@@ -247,9 +237,7 @@ def flash_board(
247
237
  for mcu, fw_info in todo:
248
238
  fw_file = fw_folder / fw_info["filename"] # type: ignore
249
239
  if not fw_file.exists():
250
- log.error(
251
- f"File {fw_file} does not exist, skipping {mcu.board} on {mcu.serialport}"
252
- )
240
+ log.error(f"File {fw_file} does not exist, skipping {mcu.board} on {mcu.serialport}")
253
241
  continue
254
242
  log.info(f"Updating {mcu.board} on {mcu.serialport} to {fw_info['version']}")
255
243
 
@@ -269,12 +257,13 @@ def flash_board(
269
257
 
270
258
  if flashed:
271
259
  log.info(f"Flashed {len(flashed)} boards")
272
- conn_boards = [
273
- MPRemoteBoard(sp)
274
- for sp in MPRemoteBoard.connected_boards()
275
- if sp not in config.ignore_ports
276
- ]
277
- show_boards(conn_boards, title="Connected boards after flashing")
260
+ # conn_boards = [
261
+ # MPRemoteBoard(sp)
262
+ # for sp in MPRemoteBoard.connected_boards()
263
+ # if sp not in config.ignore_ports
264
+ # ]
265
+
266
+ show_boards(flashed, title="Connected boards after flashing")
278
267
 
279
268
 
280
269
  # TODO:
@@ -24,11 +24,7 @@ from .config import config
24
24
  help="""Output in json format""",
25
25
  )
26
26
  def list_boards(as_json: bool):
27
- conn_boards = [
28
- MPRemoteBoard(sp)
29
- for sp in MPRemoteBoard.connected_boards()
30
- if sp not in config.ignore_ports
31
- ]
27
+ conn_boards = [MPRemoteBoard(sp) for sp in MPRemoteBoard.connected_boards() if sp not in config.ignore_ports]
32
28
 
33
29
  for mcu in track(conn_boards, description="Getting board info"):
34
30
  try:
@@ -813,45 +813,41 @@ files = [
813
813
 
814
814
  [[package]]
815
815
  name = "micropython-stubber"
816
- version = "1.17.3"
816
+ version = "1.17.4"
817
817
  description = "Tooling to create and maintain stubs for MicroPython"
818
818
  optional = false
819
819
  python-versions = ">=3.9,<3.12"
820
- files = []
821
- develop = false
820
+ files = [
821
+ {file = "micropython_stubber-1.17.4-py3-none-any.whl", hash = "sha256:8daae4ffcdacd523f1e8577873b3d5c7b27f293808b7b161b79c4400bbfd1db6"},
822
+ {file = "micropython_stubber-1.17.4.tar.gz", hash = "sha256:da9132ad5b601d06c2e84aaf3741f17d9873966274c503d7a95e41466dc91fab"},
823
+ ]
822
824
 
823
825
  [package.dependencies]
824
826
  autoflake = ">=1.7,<3.0"
825
827
  black = ">=22.10,<23.0"
826
- cachetools = "^5.3.0"
827
- click = "^8.1.3"
828
- executing = "^2.0.1"
829
- libcst = "^1.1.0"
828
+ cachetools = ">=5.3.0,<6.0.0"
829
+ click = ">=8.1.3,<9.0.0"
830
+ executing = ">=2.0.1,<3.0.0"
831
+ libcst = ">=1.1.0,<2.0.0"
830
832
  loguru = ">=0.6,<0.8"
831
- mpremote = "^1.22.0"
833
+ mpremote = ">=1.22.0,<2.0.0"
832
834
  mypy = "1.7.0"
833
- mypy-gitlab-code-quality = "^1.1.0"
835
+ mypy-gitlab-code-quality = ">=1.1.0,<2.0.0"
834
836
  packaging = ">=21.3,<24.0"
835
- pipx = "^1.1.0"
836
- pygithub = "^2.1.1"
837
- pypi-simple = "^1.0.0"
838
- pyright = "^1.1.341"
839
- pyserial = "^3.5"
840
- pysondb-v2 = "^2.1.0"
841
- python-minifier = {version = "^2.7.0", markers = "python_version < \"3.12\""}
842
- requests = "^2.28.0"
843
- rich-click = "^1.7.3"
844
- tabulate = "^0.9.0"
845
- tenacity = "^8.2.2"
846
- tomli = {version = "^2.0.1", markers = "python_version < \"3.11\""}
847
- tomli-w = "^1.0.0"
848
- typed-config = "^1.3.0"
849
-
850
- [package.source]
851
- type = "git"
852
- url = "https://github.com/josverl/micropython-stubber.git"
853
- reference = "action_board_stubber"
854
- resolved_reference = "8a41135ed57256fc603a6feb857ffc091196dad8"
837
+ pipx = ">=1.1.0,<2.0.0"
838
+ pygithub = ">=2.1.1,<3.0.0"
839
+ pypi-simple = ">=1.0.0,<2.0.0"
840
+ pyright = ">=1.1.341,<2.0.0"
841
+ pyserial = ">=3.5,<4.0"
842
+ pysondb-v2 = ">=2.1.0,<3.0.0"
843
+ python-minifier = {version = ">=2.7.0,<3.0.0", markers = "python_version < \"3.12\""}
844
+ requests = ">=2.28.0,<3.0.0"
845
+ rich-click = ">=1.7.3,<2.0.0"
846
+ tabulate = ">=0.9.0,<0.10.0"
847
+ tenacity = ">=8.2.2,<9.0.0"
848
+ tomli = {version = ">=2.0.1,<3.0.0", markers = "python_version < \"3.11\""}
849
+ tomli-w = ">=1.0.0,<2.0.0"
850
+ typed-config = ">=1.3.0,<2.0.0"
855
851
 
856
852
  [[package]]
857
853
  name = "mpremote"
@@ -1374,6 +1370,7 @@ files = [
1374
1370
  {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"},
1375
1371
  {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"},
1376
1372
  {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"},
1373
+ {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"},
1377
1374
  {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"},
1378
1375
  {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"},
1379
1376
  {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"},
@@ -1780,4 +1777,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p
1780
1777
  [metadata]
1781
1778
  lock-version = "2.0"
1782
1779
  python-versions = ">=3.9,<3.12"
1783
- content-hash = "36c40f30eed93cb30f39fd83b79a71a2bdbfd68b0c9a400248089b0a524246da"
1780
+ content-hash = "f759dfee8eeeb1da187db90a1a4a53c08e0029961413ce4bfc209b8593d6f3b0"
mpflash/pyproject.toml ADDED
@@ -0,0 +1,41 @@
1
+ [tool.poetry]
2
+ name = "mpflash"
3
+ version = "0.2.3"
4
+ description = "Download and flash tool for MicroPython firmwares"
5
+ authors = ["Jos Verlinde <jos_verlinde@hotmail.com>"]
6
+ license = "MIT"
7
+ readme = "README.md"
8
+ keywords = ["MicroPython", "firmware", "flash", "download", "UF2", "esptool"]
9
+ homepage = "https://github.com/Josverl/micropython-stubber/blob/main/src/mpflash/README.md"
10
+ repository = "https://github.com/Josverl/micropython-stubber"
11
+ classifiers = [
12
+ "Programming Language :: Python :: Implementation :: MicroPython",
13
+ "Programming Language :: Python :: Implementation :: CPython",
14
+ "Topic :: Software Development :: Build Tools",
15
+ ]
16
+
17
+ [tool.poetry.scripts]
18
+ mpflash = "mpflash.cli_main:mpflash"
19
+
20
+ [tool.poetry.dependencies]
21
+ python = ">=3.9,<3.12"
22
+ requests = "^2.31.0"
23
+ beautifulsoup4 = "^4.12.3"
24
+ loguru = "^0.7.2"
25
+ esptool = "^4.7.0"
26
+ jsonlines = "^4.0.0"
27
+ bincopy = "^20.0.0"
28
+ strip-ansi = "^0.1.1"
29
+ rich-click = "^1.7.3"
30
+ micropython-stubber = ">=1.17.4"
31
+ psutil = "^5.9.8"
32
+ blkinfo = "^0.2.0"
33
+ pygithub = "^2.1.1"
34
+ platformdirs = "^4.2.0"
35
+
36
+ [tool.poetry.group.dev.dependencies]
37
+ types-beautifulsoup4 = "^4.12.0.20240106"
38
+
39
+ [build-system]
40
+ requires = ["poetry-core"]
41
+ build-backend = "poetry.core.masonry.api"
stubber/__init__.py CHANGED
@@ -1,4 +1,3 @@
1
1
  """get the version"""
2
2
 
3
-
4
- __version__ = "1.17.4"
3
+ __version__ = "1.17.6"
@@ -24,7 +24,7 @@ try:
24
24
  except ImportError:
25
25
  from ucollections import OrderedDict # type: ignore
26
26
 
27
- __version__ = "v1.17.4"
27
+ __version__ = "v1.17.6"
28
28
  ENOENT = 2
29
29
  _MAX_CLASS_LEVEL = 2 # Max class nesting
30
30
  LIBS = ["lib", "/lib", "/sd/lib", "/flash/lib", "."]
@@ -363,6 +363,8 @@ class Stubber:
363
363
  else:
364
364
  # Requires Python 3.6 syntax, which is OK for the stubs/pyi
365
365
  t = "Incomplete"
366
+ if " at " in item_repr:
367
+ item_repr = item_repr.split(" at ")[0] + " at ...>"
366
368
  if " at " in item_repr:
367
369
  item_repr = item_repr.split(" at ")[0] + " at ...>"
368
370
  s = "{0}{1}: {2} ## {3} = {4}\n".format(indent, item_name, t, item_type_txt, item_repr)
@@ -18,7 +18,7 @@ Create stubs for (all) modules on a MicroPython board.
18
18
  - cross compilation, using mpy-cross, to avoid the compilation step on the micropython device
19
19
 
20
20
 
21
- This variant was generated from createstubs.py by micropython-stubber v1.17.4
21
+ This variant was generated from createstubs.py by micropython-stubber v1.17.6
22
22
  """
23
23
 
24
24
  # Copyright (c) 2019-2023 Jos Verlinde
@@ -43,7 +43,7 @@ try:
43
43
  except ImportError:
44
44
  from ucollections import OrderedDict # type: ignore
45
45
 
46
- __version__ = "v1.17.4"
46
+ __version__ = "v1.17.6"
47
47
  ENOENT = 2
48
48
  _MAX_CLASS_LEVEL = 2 # Max class nesting
49
49
  LIBS = ["lib", "/lib", "/sd/lib", "/flash/lib", "."]
@@ -376,6 +376,8 @@ class Stubber:
376
376
  else:
377
377
  # Requires Python 3.6 syntax, which is OK for the stubs/pyi
378
378
  t = "Incomplete"
379
+ if " at " in item_repr:
380
+ item_repr = item_repr.split(" at ")[0] + " at ...>"
379
381
  if " at " in item_repr:
380
382
  item_repr = item_repr.split(" at ")[0] + " at ...>"
381
383
  s = "{0}{1}: {2} ## {3} = {4}\n".format(indent, item_name, t, item_type_txt, item_repr)
@@ -51,7 +51,7 @@ try:from machine import reset
51
51
  except O:pass
52
52
  try:from collections import OrderedDict as k
53
53
  except O:from ucollections import OrderedDict as k
54
- __version__='v1.17.4'
54
+ __version__='v1.17.6'
55
55
  A3=2
56
56
  A4=2
57
57
  A5=['lib','/lib','/sd/lib','/flash/lib',J]
@@ -131,40 +131,41 @@ class Stubber:
131
131
  try:del N
132
132
  except(D,q):A.warning('could not del new_module')
133
133
  F.collect();return R
134
- def write_object_stub(K,fp,object_expr,obj_name,indent,in_class=0):
135
- Y=' at ';X='generator';W='{0}{1}: {3} = {2}\n';V='bound_method';U='Incomplete';N=in_class;M='Exception';L=object_expr;I=fp;D=indent;F.collect()
136
- if L in K.problematic:A.warning('SKIPPING problematic module:{}'.format(L));return
137
- Z,O=K.get_obj_attributes(L)
138
- if O:A.error(O)
139
- for(E,J,H,a,c)in Z:
140
- if E in['classmethod','staticmethod','BaseException',M]:continue
134
+ def write_object_stub(L,fp,object_expr,obj_name,indent,in_class=0):
135
+ Z=' at ...>';Y='generator';X='{0}{1}: {3} = {2}\n';W='bound_method';V='Incomplete';O=in_class;N='Exception';M=object_expr;K=' at ';J=fp;D=indent;F.collect()
136
+ if M in L.problematic:A.warning('SKIPPING problematic module:{}'.format(M));return
137
+ a,Q=L.get_obj_attributes(M)
138
+ if Q:A.error(Q)
139
+ for(E,H,I,b,g)in a:
140
+ if E in['classmethod','staticmethod','BaseException',N]:continue
141
141
  if E[0].isdigit():A.warning('NameError: invalid name {}'.format(E));continue
142
- if H=="<class 'type'>"and P(D)<=A4*4:
143
- Q=B;R=E.endswith(M)or E.endswith('Error')or E in['KeyboardInterrupt','StopIteration','SystemExit']
144
- if R:Q=M
145
- C='\n{}class {}({}):\n'.format(D,E,Q)
146
- if R:C+=D+' ...\n';I.write(C);continue
147
- I.write(C);K.write_object_stub(I,a,'{0}.{1}'.format(obj_name,E),D+' ',N+1);C=D+' def __init__(self, *argv, **kwargs) -> None:\n';C+=D+' ...\n\n';I.write(C)
148
- elif any(A in H for A in[A0,z,'closure']):
149
- S=U;T=B
150
- if N>0:T='self, '
151
- if V in H or V in J:C='{}@classmethod\n'.format(D)+'{}def {}(cls, *args, **kwargs) -> {}:\n'.format(D,E,S)
152
- else:C='{}def {}({}*args, **kwargs) -> {}:\n'.format(D,E,T,S)
153
- C+=D+' ...\n\n';I.write(C)
154
- elif H=="<class 'module'>":0
155
- elif H.startswith("<class '"):
156
- G=H[8:-2];C=B
157
- if G in(x,v,w,y,'bytearray','bytes'):C=W.format(D,E,J,G)
158
- elif G in(f,e,d):b={f:'{}',e:'[]',d:'()'};C=W.format(D,E,b[G],G)
159
- elif G in('object','set','frozenset','Pin',X):
160
- if G==X:G='Generator'
161
- C='{0}{1}: {2} ## = {4}\n'.format(D,E,G,H,J)
142
+ if I=="<class 'type'>"and P(D)<=A4*4:
143
+ R=B;S=E.endswith(N)or E.endswith('Error')or E in['KeyboardInterrupt','StopIteration','SystemExit']
144
+ if S:R=N
145
+ C='\n{}class {}({}):\n'.format(D,E,R)
146
+ if S:C+=D+' ...\n';J.write(C);continue
147
+ J.write(C);L.write_object_stub(J,b,'{0}.{1}'.format(obj_name,E),D+' ',O+1);C=D+' def __init__(self, *argv, **kwargs) -> None:\n';C+=D+' ...\n\n';J.write(C)
148
+ elif any(A in I for A in[A0,z,'closure']):
149
+ T=V;U=B
150
+ if O>0:U='self, '
151
+ if W in I or W in H:C='{}@classmethod\n'.format(D)+'{}def {}(cls, *args, **kwargs) -> {}:\n'.format(D,E,T)
152
+ else:C='{}def {}({}*args, **kwargs) -> {}:\n'.format(D,E,U,T)
153
+ C+=D+' ...\n\n';J.write(C)
154
+ elif I=="<class 'module'>":0
155
+ elif I.startswith("<class '"):
156
+ G=I[8:-2];C=B
157
+ if G in(x,v,w,y,'bytearray','bytes'):C=X.format(D,E,H,G)
158
+ elif G in(f,e,d):c={f:'{}',e:'[]',d:'()'};C=X.format(D,E,c[G],G)
159
+ elif G in('object','set','frozenset','Pin',Y):
160
+ if G==Y:G='Generator'
161
+ C='{0}{1}: {2} ## = {4}\n'.format(D,E,G,I,H)
162
162
  else:
163
- G=U
164
- if Y in J:J=J.split(Y)[0]+' at ...>'
165
- C='{0}{1}: {2} ## {3} = {4}\n'.format(D,E,G,H,J)
166
- I.write(C)
167
- else:I.write("# all other, type = '{0}'\n".format(H));I.write(D+E+' # type: Incomplete\n')
163
+ G=V
164
+ if K in H:H=H.split(K)[0]+Z
165
+ if K in H:H=H.split(K)[0]+Z
166
+ C='{0}{1}: {2} ## {3} = {4}\n'.format(D,E,G,I,H)
167
+ J.write(C)
168
+ else:J.write("# all other, type = '{0}'\n".format(I));J.write(D+E+' # type: Incomplete\n')
168
169
  @property
169
170
  def flat_fwid(self):
170
171
  A=self._fwid;B=' .()/\\:$'
Binary file
@@ -9,7 +9,7 @@
9
9
  - cross compilation, using mpy-cross,
10
10
  to avoid the compilation step on the micropython device
11
11
 
12
- This variant was generated from createstubs.py by micropython-stubber v1.17.4
12
+ This variant was generated from createstubs.py by micropython-stubber v1.17.6
13
13
  """
14
14
 
15
15
  # Copyright (c) 2019-2023 Jos Verlinde
@@ -34,7 +34,7 @@ try:
34
34
  except ImportError:
35
35
  from ucollections import OrderedDict # type: ignore
36
36
 
37
- __version__ = "v1.17.4"
37
+ __version__ = "v1.17.6"
38
38
  ENOENT = 2
39
39
  _MAX_CLASS_LEVEL = 2 # Max class nesting
40
40
  LIBS = ["lib", "/lib", "/sd/lib", "/flash/lib", "."]
@@ -367,6 +367,8 @@ class Stubber:
367
367
  else:
368
368
  # Requires Python 3.6 syntax, which is OK for the stubs/pyi
369
369
  t = "Incomplete"
370
+ if " at " in item_repr:
371
+ item_repr = item_repr.split(" at ")[0] + " at ...>"
370
372
  if " at " in item_repr:
371
373
  item_repr = item_repr.split(" at ")[0] + " at ...>"
372
374
  s = "{0}{1}: {2} ## {3} = {4}\n".format(indent, item_name, t, item_type_txt, item_repr)
@@ -47,7 +47,7 @@ try:from machine import reset
47
47
  except N:pass
48
48
  try:from collections import OrderedDict as f
49
49
  except N:from ucollections import OrderedDict as f
50
- __version__='v1.17.4'
50
+ __version__='v1.17.6'
51
51
  y=2
52
52
  z=2
53
53
  A0=['lib','/lib','/sd/lib','/flash/lib',J]
@@ -127,40 +127,41 @@ class Stubber:
127
127
  try:del M
128
128
  except(F,l):A.warning('could not del new_module')
129
129
  D.collect();return R
130
- def write_object_stub(K,fp,object_expr,obj_name,indent,in_class=0):
131
- Y=' at ';X='generator';W='{0}{1}: {3} = {2}\n';V='bound_method';U='Incomplete';N=in_class;M='Exception';L=object_expr;I=fp;E=indent;D.collect()
132
- if L in K.problematic:A.warning('SKIPPING problematic module:{}'.format(L));return
133
- Z,O=K.get_obj_attributes(L)
134
- if O:A.error(O)
135
- for(F,J,H,a,f)in Z:
136
- if F in['classmethod','staticmethod','BaseException',M]:continue
130
+ def write_object_stub(L,fp,object_expr,obj_name,indent,in_class=0):
131
+ Z=' at ...>';Y='generator';X='{0}{1}: {3} = {2}\n';W='bound_method';V='Incomplete';O=in_class;N='Exception';M=object_expr;K=' at ';J=fp;E=indent;D.collect()
132
+ if M in L.problematic:A.warning('SKIPPING problematic module:{}'.format(M));return
133
+ a,Q=L.get_obj_attributes(M)
134
+ if Q:A.error(Q)
135
+ for(F,H,I,e,g)in a:
136
+ if F in['classmethod','staticmethod','BaseException',N]:continue
137
137
  if F[0].isdigit():A.warning('NameError: invalid name {}'.format(F));continue
138
- if H=="<class 'type'>"and P(E)<=z*4:
139
- Q=B;R=F.endswith(M)or F.endswith('Error')or F in['KeyboardInterrupt','StopIteration','SystemExit']
140
- if R:Q=M
141
- C='\n{}class {}({}):\n'.format(E,F,Q)
142
- if R:C+=E+' ...\n';I.write(C);continue
143
- I.write(C);K.write_object_stub(I,a,'{0}.{1}'.format(obj_name,F),E+' ',N+1);C=E+' def __init__(self, *argv, **kwargs) -> None:\n';C+=E+' ...\n\n';I.write(C)
144
- elif any(A in H for A in[u,t,'closure']):
145
- S=U;T=B
146
- if N>0:T='self, '
147
- if V in H or V in J:C='{}@classmethod\n'.format(E)+'{}def {}(cls, *args, **kwargs) -> {}:\n'.format(E,F,S)
148
- else:C='{}def {}({}*args, **kwargs) -> {}:\n'.format(E,F,T,S)
149
- C+=E+' ...\n\n';I.write(C)
150
- elif H=="<class 'module'>":0
151
- elif H.startswith("<class '"):
152
- G=H[8:-2];C=B
153
- if G in(r,p,q,s,'bytearray','bytes'):C=W.format(E,F,J,G)
154
- elif G in(d,c,b):e={d:'{}',c:'[]',b:'()'};C=W.format(E,F,e[G],G)
155
- elif G in('object','set','frozenset','Pin',X):
156
- if G==X:G='Generator'
157
- C='{0}{1}: {2} ## = {4}\n'.format(E,F,G,H,J)
138
+ if I=="<class 'type'>"and P(E)<=z*4:
139
+ R=B;S=F.endswith(N)or F.endswith('Error')or F in['KeyboardInterrupt','StopIteration','SystemExit']
140
+ if S:R=N
141
+ C='\n{}class {}({}):\n'.format(E,F,R)
142
+ if S:C+=E+' ...\n';J.write(C);continue
143
+ J.write(C);L.write_object_stub(J,e,'{0}.{1}'.format(obj_name,F),E+' ',O+1);C=E+' def __init__(self, *argv, **kwargs) -> None:\n';C+=E+' ...\n\n';J.write(C)
144
+ elif any(A in I for A in[u,t,'closure']):
145
+ T=V;U=B
146
+ if O>0:U='self, '
147
+ if W in I or W in H:C='{}@classmethod\n'.format(E)+'{}def {}(cls, *args, **kwargs) -> {}:\n'.format(E,F,T)
148
+ else:C='{}def {}({}*args, **kwargs) -> {}:\n'.format(E,F,U,T)
149
+ C+=E+' ...\n\n';J.write(C)
150
+ elif I=="<class 'module'>":0
151
+ elif I.startswith("<class '"):
152
+ G=I[8:-2];C=B
153
+ if G in(r,p,q,s,'bytearray','bytes'):C=X.format(E,F,H,G)
154
+ elif G in(d,c,b):f={d:'{}',c:'[]',b:'()'};C=X.format(E,F,f[G],G)
155
+ elif G in('object','set','frozenset','Pin',Y):
156
+ if G==Y:G='Generator'
157
+ C='{0}{1}: {2} ## = {4}\n'.format(E,F,G,I,H)
158
158
  else:
159
- G=U
160
- if Y in J:J=J.split(Y)[0]+' at ...>'
161
- C='{0}{1}: {2} ## {3} = {4}\n'.format(E,F,G,H,J)
162
- I.write(C)
163
- else:I.write("# all other, type = '{0}'\n".format(H));I.write(E+F+' # type: Incomplete\n')
159
+ G=V
160
+ if K in H:H=H.split(K)[0]+Z
161
+ if K in H:H=H.split(K)[0]+Z
162
+ C='{0}{1}: {2} ## {3} = {4}\n'.format(E,F,G,I,H)
163
+ J.write(C)
164
+ else:J.write("# all other, type = '{0}'\n".format(I));J.write(E+F+' # type: Incomplete\n')
164
165
  @property
165
166
  def flat_fwid(self):
166
167
  A=self._fwid;B=' .()/\\:$'
Binary file
@@ -50,7 +50,7 @@ try:from machine import reset
50
50
  except N:pass
51
51
  try:from collections import OrderedDict as g
52
52
  except N:from ucollections import OrderedDict as g
53
- __version__='v1.17.4'
53
+ __version__='v1.17.6'
54
54
  A0=2
55
55
  A1=2
56
56
  A5=['lib','/lib','/sd/lib','/flash/lib',J]
@@ -130,40 +130,41 @@ class Stubber:
130
130
  try:del M
131
131
  except(E,l):A.warning('could not del new_module')
132
132
  F.collect();return U
133
- def write_object_stub(K,fp,object_expr,obj_name,indent,in_class=0):
134
- Y=' at ';X='generator';W='{0}{1}: {3} = {2}\n';V='bound_method';U='Incomplete';N=in_class;M='Exception';L=object_expr;I=fp;D=indent;F.collect()
135
- if L in K.problematic:A.warning('SKIPPING problematic module:{}'.format(L));return
136
- Z,O=K.get_obj_attributes(L)
137
- if O:A.error(O)
138
- for(E,J,H,a,f)in Z:
139
- if E in['classmethod','staticmethod','BaseException',M]:continue
133
+ def write_object_stub(L,fp,object_expr,obj_name,indent,in_class=0):
134
+ Z=' at ...>';Y='generator';X='{0}{1}: {3} = {2}\n';W='bound_method';V='Incomplete';O=in_class;N='Exception';M=object_expr;K=' at ';J=fp;D=indent;F.collect()
135
+ if M in L.problematic:A.warning('SKIPPING problematic module:{}'.format(M));return
136
+ a,P=L.get_obj_attributes(M)
137
+ if P:A.error(P)
138
+ for(E,H,I,e,g)in a:
139
+ if E in['classmethod','staticmethod','BaseException',N]:continue
140
140
  if E[0].isdigit():A.warning('NameError: invalid name {}'.format(E));continue
141
- if H=="<class 'type'>"and R(D)<=A1*4:
142
- P=B;Q=E.endswith(M)or E.endswith('Error')or E in['KeyboardInterrupt','StopIteration','SystemExit']
143
- if Q:P=M
144
- C='\n{}class {}({}):\n'.format(D,E,P)
145
- if Q:C+=D+' ...\n';I.write(C);continue
146
- I.write(C);K.write_object_stub(I,a,'{0}.{1}'.format(obj_name,E),D+' ',N+1);C=D+' def __init__(self, *argv, **kwargs) -> None:\n';C+=D+' ...\n\n';I.write(C)
147
- elif any(A in H for A in[u,t,'closure']):
148
- S=U;T=B
149
- if N>0:T='self, '
150
- if V in H or V in J:C='{}@classmethod\n'.format(D)+'{}def {}(cls, *args, **kwargs) -> {}:\n'.format(D,E,S)
151
- else:C='{}def {}({}*args, **kwargs) -> {}:\n'.format(D,E,T,S)
152
- C+=D+' ...\n\n';I.write(C)
153
- elif H=="<class 'module'>":0
154
- elif H.startswith("<class '"):
155
- G=H[8:-2];C=B
156
- if G in(r,p,q,s,'bytearray','bytes'):C=W.format(D,E,J,G)
157
- elif G in(d,c,b):e={d:'{}',c:'[]',b:'()'};C=W.format(D,E,e[G],G)
158
- elif G in('object','set','frozenset','Pin',X):
159
- if G==X:G='Generator'
160
- C='{0}{1}: {2} ## = {4}\n'.format(D,E,G,H,J)
141
+ if I=="<class 'type'>"and R(D)<=A1*4:
142
+ Q=B;S=E.endswith(N)or E.endswith('Error')or E in['KeyboardInterrupt','StopIteration','SystemExit']
143
+ if S:Q=N
144
+ C='\n{}class {}({}):\n'.format(D,E,Q)
145
+ if S:C+=D+' ...\n';J.write(C);continue
146
+ J.write(C);L.write_object_stub(J,e,'{0}.{1}'.format(obj_name,E),D+' ',O+1);C=D+' def __init__(self, *argv, **kwargs) -> None:\n';C+=D+' ...\n\n';J.write(C)
147
+ elif any(A in I for A in[u,t,'closure']):
148
+ T=V;U=B
149
+ if O>0:U='self, '
150
+ if W in I or W in H:C='{}@classmethod\n'.format(D)+'{}def {}(cls, *args, **kwargs) -> {}:\n'.format(D,E,T)
151
+ else:C='{}def {}({}*args, **kwargs) -> {}:\n'.format(D,E,U,T)
152
+ C+=D+' ...\n\n';J.write(C)
153
+ elif I=="<class 'module'>":0
154
+ elif I.startswith("<class '"):
155
+ G=I[8:-2];C=B
156
+ if G in(r,p,q,s,'bytearray','bytes'):C=X.format(D,E,H,G)
157
+ elif G in(d,c,b):f={d:'{}',c:'[]',b:'()'};C=X.format(D,E,f[G],G)
158
+ elif G in('object','set','frozenset','Pin',Y):
159
+ if G==Y:G='Generator'
160
+ C='{0}{1}: {2} ## = {4}\n'.format(D,E,G,I,H)
161
161
  else:
162
- G=U
163
- if Y in J:J=J.split(Y)[0]+' at ...>'
164
- C='{0}{1}: {2} ## {3} = {4}\n'.format(D,E,G,H,J)
165
- I.write(C)
166
- else:I.write("# all other, type = '{0}'\n".format(H));I.write(D+E+' # type: Incomplete\n')
162
+ G=V
163
+ if K in H:H=H.split(K)[0]+Z
164
+ if K in H:H=H.split(K)[0]+Z
165
+ C='{0}{1}: {2} ## {3} = {4}\n'.format(D,E,G,I,H)
166
+ J.write(C)
167
+ else:J.write("# all other, type = '{0}'\n".format(I));J.write(D+E+' # type: Incomplete\n')
167
168
  @property
168
169
  def flat_fwid(self):
169
170
  A=self._fwid;B=' .()/\\:$'
Binary file
stubber/bulk/runner.py CHANGED
@@ -11,6 +11,7 @@ from loguru import logger as log
11
11
 
12
12
  LogTagList = List[str]
13
13
 
14
+
14
15
  @dataclass
15
16
  class LogTags:
16
17
  reset_tags: LogTagList
@@ -115,9 +116,10 @@ def run(
115
116
  if proc.stderr and log_errors:
116
117
  for line in proc.stderr:
117
118
  log.warning(line)
119
+ except UnicodeDecodeError as e:
120
+ log.error(f"Failed to decode output: {e}")
118
121
  finally:
119
122
  timer.cancel()
120
123
 
121
124
  proc.wait(timeout=1)
122
125
  return proc.returncode or 0, output
123
-
mptool/README.md DELETED
@@ -1,10 +0,0 @@
1
- Download script
2
-
3
-
4
- install using
5
-
6
- pip install git+https://github.com/josverl/micropython-stubber.git@main#subdirectory=modules/mp_downloader
7
-
8
- Development:
9
-
10
- pip install git+https://github.com/josverl/micropython-stubber.git@action_board_stubber#subdirectory=modules/mp_downloader
mptool/pyproject.toml DELETED
@@ -1,34 +0,0 @@
1
- [tool.poetry]
2
- name = "mptool"
3
- version = "0.2.0"
4
- description = "Download and flashing tool for MicroPython firmwares"
5
- authors = ["Jos Verlinde <jos.verlinde@microsoft.com>"]
6
- license = "MIT"
7
- readme = "README.md"
8
- # packages = [{ include = "**/*.*", from = "src" }]
9
-
10
- [tool.poetry.scripts]
11
- mptool = "mptool.cli_main:mptool"
12
-
13
-
14
- [tool.poetry.dependencies]
15
- python = ">=3.9,<3.12"
16
- requests = "^2.31.0"
17
- beautifulsoup4 = "^4.12.3"
18
- loguru = "^0.7.2"
19
- esptool = "^4.7.0"
20
- jsonlines = "^4.0.0"
21
- bincopy = "^20.0.0"
22
- strip-ansi = "^0.1.1"
23
- rich-click = "^1.7.3"
24
- micropython-stubber = {git = "https://github.com/josverl/micropython-stubber.git", rev = "action_board_stubber"}
25
- psutil = "^5.9.8"
26
- blkinfo = "^0.2.0"
27
- pygithub = "^2.1.1"
28
-
29
- [tool.poetry.group.dev.dependencies]
30
- types-beautifulsoup4 = "^4.12.0.20240106"
31
-
32
- [build-system]
33
- requires = ["poetry-core"]
34
- build-backend = "poetry.core.masonry.api"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes