micropython-stubber 1.20.2__py3-none-any.whl → 1.20.4__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: micropython-stubber
3
- Version: 1.20.2
3
+ Version: 1.20.4
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
@@ -13,6 +13,7 @@ Classifier: Programming Language :: Python :: 3
13
13
  Classifier: Programming Language :: Python :: 3.9
14
14
  Classifier: Programming Language :: Python :: 3.10
15
15
  Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
16
17
  Classifier: Programming Language :: Python :: Implementation :: CPython
17
18
  Classifier: Programming Language :: Python :: Implementation :: MicroPython
18
19
  Classifier: Topic :: Software Development :: Build Tools
@@ -4,33 +4,33 @@ mpflash/mpflash/add_firmware.py,sha256=u_g9mID557fptLEJ1Nld9n27V1R1og8uEkadm0O3Y
4
4
  mpflash/mpflash/ask_input.py,sha256=e54WfgktG7Ff8dBUknXioROq3lPNZ-eacUjfmUvFfS0,8496
5
5
  mpflash/mpflash/cli_download.py,sha256=6ctC4ga6q2LcpHUHMrz1trbePziQpuIFPbjcJnc3K7E,3645
6
6
  mpflash/mpflash/cli_flash.py,sha256=QHEb-e2ABjISfuGCWpTxOM7kkcTZSQxBXmVaWh3WVnE,7074
7
- mpflash/mpflash/cli_group.py,sha256=-qkR4ou7bmIwfDIzyL1s34z6ya1wckKtL22nanvyQGU,1974
7
+ mpflash/mpflash/cli_group.py,sha256=nrihkm74X8pX1jPM72W8ljoc5rYL6ggGOQFRaOldhLo,2038
8
8
  mpflash/mpflash/cli_list.py,sha256=Mdaf13gKZCoLp8Y2ja0L5rYMzkE_t3d4r62bF7isI3E,1997
9
9
  mpflash/mpflash/cli_main.py,sha256=yABFFf45TpPMcC1qEVARAWe4EI9zui2pUXjoPms0mq8,1030
10
- mpflash/mpflash/common.py,sha256=kanbO22SQDWb4ASQG8vLF0Z83ahujKPbrsCw3llN5T4,5594
11
- mpflash/mpflash/config.py,sha256=hBc1Hf4XQ0YIoeiPBbannnqDg0C7226Y7Vu8o4jUkBQ,495
10
+ mpflash/mpflash/common.py,sha256=MmyLadb_z7bhVy6U8jb4f3pnBK8n7x28smFBcA9ZfGg,5608
11
+ mpflash/mpflash/config.py,sha256=R7PomStIFHSTnLhpWhw9P2DL_b-8a8Wrja3aY-dPm6A,762
12
12
  mpflash/mpflash/connected.py,sha256=CBG_DJ33OPWAPbX-ICQpL1LcFOhNYpLUSB0Q5v7gi9s,3029
13
- mpflash/mpflash/download.py,sha256=axAs30i7VZ0jQXY9MVOQB49JH6OCFxy5_zERfysF33I,11421
14
- mpflash/mpflash/downloaded.py,sha256=IYMyx_67paKFSKOg3whgwsWf8IlHaLgpmSlukMT7V9Q,3804
13
+ mpflash/mpflash/download.py,sha256=NErA2SJEhXnTElvq6z4BJl-L-5M_ETJpqX6pM0oubsg,14290
14
+ mpflash/mpflash/downloaded.py,sha256=FQuVl21bx4JotfnXufoihexKeJt3gDMqhSWUvVKBSDk,4868
15
15
  mpflash/mpflash/errors.py,sha256=Q5LR12Wo8iUCg5n_qq4GjdBdBflbvCOdKsRJ5InYRfI,96
16
16
  mpflash/mpflash/flash.py,sha256=JoskuwaHVYqeG4YW8kgbv26vPFnqDmkTz1VRs-pTRiY,2468
17
17
  mpflash/mpflash/flash_esp.py,sha256=dEc_B7-f1BMUGBMrwIm83ulcCqaS5MlrPAp3FCNgNfk,2311
18
18
  mpflash/mpflash/flash_stm32.py,sha256=d4BoQl3a9Tchnvn2ZTuq2MpYBB4MTaRukwtEncI95k0,823
19
19
  mpflash/mpflash/flash_stm32_cube.py,sha256=w7aGWjReeWUKl0Q3ZjXH8BRqNO1Tk9AO7gtRNUg1c9Y,3970
20
20
  mpflash/mpflash/flash_stm32_dfu.py,sha256=G70EZodWb-aRi507Jxbys-VEwbBGU1oZacow3_nq-d4,2972
21
- mpflash/mpflash/flash_uf2.py,sha256=FFO2zpKFPdpEDi4aK1-JFsvPi8KEKLXXuOt_lXtI9tk,2508
22
- mpflash/mpflash/flash_uf2_boardid.py,sha256=WZKucGu_hJ8ymb236uuZbiR6pD6AA_l4LA-7LwtQhq8,414
21
+ mpflash/mpflash/flash_uf2.py,sha256=2IKgEOnlsB9bILJWHILMKbGo9b39NKazBWp1-T_eKKs,2463
22
+ mpflash/mpflash/flash_uf2_boardid.py,sha256=U5wGM8VA3wEpUxQCMtuXpMZZomdVH8J_Zd5_GekUMuU,423
23
23
  mpflash/mpflash/flash_uf2_linux.py,sha256=Oy9V4g7JSuks2hHFeO_OHdBKSGktbqZOtsivuxfl-xg,4055
24
- mpflash/mpflash/flash_uf2_macos.py,sha256=JButLjccuKlVyArwNkHDGjNMB_9ezyTKlbCWNia-R5Y,2696
25
- mpflash/mpflash/flash_uf2_windows.py,sha256=94YoO2UIzfyJs4CPJ9sjG_WY26SX8aUPl9mf9R9W5xk,1093
24
+ mpflash/mpflash/flash_uf2_macos.py,sha256=HGUg2HSw4qalfSP7npLYgos2WlVRxtOVTDcAnBL7qPY,1078
25
+ mpflash/mpflash/flash_uf2_windows.py,sha256=a-iIGPkwIoUXA7atCz0_uZp-kipSL24P-IE5ka1B1Mk,1025
26
26
  mpflash/mpflash/list.py,sha256=0TawTkwhjKPPj7nTHoDn8nQ54WOkGRurP1BJVeg956g,2963
27
27
  mpflash/mpflash/logger.py,sha256=dI_H_a7EOdQJyvoeRHQuYeZuTKYVUS3DUPTLhE9rkdM,1098
28
- mpflash/mpflash/mpboard_id/__init__.py,sha256=QRLVUpeiXeiY3P-im2Bv8zX8xGS_MIqiH-3svuVoWyY,3576
28
+ mpflash/mpflash/mpboard_id/__init__.py,sha256=9IS8E-4eimd_bclgGgWE1wGEx0IRzKnu5Jzl8pQih_g,3816
29
29
  mpflash/mpflash/mpboard_id/add_boards.py,sha256=OWclyLWf9L-pCVmZ22b-xQYfvi3yQVsJHmGMgMzWxoU,9684
30
30
  mpflash/mpflash/mpboard_id/board.py,sha256=CwtBux8y7GDUe7CADVxL8YefGRl9Fg8OAJBUhgaBYCI,1151
31
- mpflash/mpflash/mpboard_id/board_id.py,sha256=63K91S_KWdSL5vHkZhpU-ibOhpOrUt0YPwxDsUBEmnc,2489
31
+ mpflash/mpflash/mpboard_id/board_id.py,sha256=uVBbqksE1S4RPO1kNAVk4-xJWj6vwAX6QeuE0ekkZEc,2964
32
32
  mpflash/mpflash/mpboard_id/board_info.zip,sha256=F6YowS96DAqjten4ySe4MXgZwPtE-saZOUfY5OQkqKk,19759
33
- mpflash/mpflash/mpboard_id/store.py,sha256=hhNTPlraQYH_Tx3syoi_NBx8z13efkgXn433OZ2GjpU,1462
33
+ mpflash/mpflash/mpboard_id/store.py,sha256=4lLEff6a30lIOb4fOYYzanE4G4qfgikfprmpV1eUf2U,1536
34
34
  mpflash/mpflash/mpremoteboard/__init__.py,sha256=fJ_N1F6R3CfP9F7pmocb5l8yRvzmSmtHi4u_uTQHR1w,7683
35
35
  mpflash/mpflash/mpremoteboard/mpy_fw_info.py,sha256=6AQbN3jtQgllqWQYl4e-63KeEtV08EXk8_JnM6XBkvo,4554
36
36
  mpflash/mpflash/mpremoteboard/runner.py,sha256=-PgzAeBGbyXaAUlwyiw4mcINsP2U1XRRjP1_QdBrxpg,4786
@@ -42,29 +42,29 @@ mpflash/mpflash/vendor/readme.md,sha256=iIIZxuLUIGHQ0KODzYVtMezsztvyxCXcNJp_AzwT
42
42
  mpflash/mpflash/vendor/versions.py,sha256=thk1a5wEEhXIQoL0zZ7oooeFyQeSoI00CIUbZF0b3rI,3783
43
43
  mpflash/mpflash/worklist.py,sha256=MKHDynttVP3lsHSfb7DEqeQ2mRV0da96lD4lIcS_zQY,5962
44
44
  mpflash/poetry.lock,sha256=pHC8OhQvF5HWKPlw2Ysd39cL4XmJIqDX_Lwo-ngm1SY,121346
45
- mpflash/pyproject.toml,sha256=xaMDME1wBJf-KTf_qqK2jlY7f3o3b1L8utaXw8ZK8PU,1651
45
+ mpflash/pyproject.toml,sha256=_5bXWE4UT_tLDBCfel76-sYQHOkreevKnB-CAoMFDNU,1651
46
46
  mpflash/README.md,sha256=1SVCxNG88akXYv1BOeLvqwfI9phy8PdkfJ2sqxL_nkE,13680
47
47
  mpflash/stm32_udev_rules.md,sha256=uxvC8FvU7K0R1QQUqCIvVfW9yfWYlIHhIVtirAjQVHE,2684
48
- stubber/__init__.py,sha256=tthm_uidIn3vd1lcFmiTkjY46W8_vGp6D9i0K_FJuds,49
48
+ stubber/__init__.py,sha256=fvRhwc22guCsHccJVu9kqJb0i049HoQgIYH47bz171s,49
49
49
  stubber/basicgit.py,sha256=sflgCv7apLbV2w8F6gmhc-3kuqDnnS4tdGol6JT2uTM,9545
50
50
  stubber/board/board_info.csv,sha256=K2VSmfR013fN-oJWkQUmiQ19w09dVwJHDquPy6QmMhY,8627
51
51
  stubber/board/boot.py,sha256=XjWlKErU5nI1HJSugXIP_3hlwgRQboE6sJrpcbSygnk,1120
52
- stubber/board/createstubs.py,sha256=eA1mHRmjhVENwtRjdcqmfC-x_U9peimZJETTBbaMagE,32739
53
- stubber/board/createstubs_db.py,sha256=xZqBLLfdrMYdG_sW_ZzvoOEFTvPcT5R5S3zN1pWhtxo,30419
54
- stubber/board/createstubs_db_min.py,sha256=J0HwWl5xsTcnq-K9hDU4V5aAxfOJqHHvNZTI-wxmLOs,11473
55
- stubber/board/createstubs_db_mpy.mpy,sha256=KJeOJW1y_PKI9hrtJaUyy07Y_DiV57rT71bolf13L-E,9536
52
+ stubber/board/createstubs.py,sha256=Mheof3vSwjyQTpm6iOBC2Svlnlz4wkIFcGQjE38V2Lk,32958
53
+ stubber/board/createstubs_db.py,sha256=iYiBM2tqlesMhIsMWsDY0pbOHQWyqW4TK_1q5RlVuUU,30419
54
+ stubber/board/createstubs_db_min.py,sha256=lzee0uRp9xCdjXL_xzViu-sDS0CrZuQM2MT82vfaYfY,11473
55
+ stubber/board/createstubs_db_mpy.mpy,sha256=X5lHvAyRh4xR4fdZCV3GrOnhPlNVGjpl5rFIaw-cZvo,9536
56
56
  stubber/board/createstubs_lvgl.py,sha256=CTe7eq1ACRK_JJxavaqDD8znn29nSWJiHHTZ_ps6EhM,27217
57
57
  stubber/board/createstubs_lvgl_min.py,sha256=jLkWYmeboI2A8feMC7pT7cYWttLejQTuX7WAEZCylhw,27207
58
58
  stubber/board/createstubs_lvgl_mpy.mpy,sha256=ex-nlq2V5e8anQBJvRWEEc-FzU7nlwg5NSrZ8vOadIA,9267
59
- stubber/board/createstubs_mem.py,sha256=_SRTvJG78fbEDCFii82Cof6cJwF_xqkXeOFDIJAx9o8,28755
60
- stubber/board/createstubs_mem_min.py,sha256=8tTzYjlgepjhepMLplN_8eOGLjEKY2NpffGPvGelP-I,11019
61
- stubber/board/createstubs_mem_mpy.mpy,sha256=RVuULJrwFQT0zJqa3JYrnOdbbU51K7rDX8mKR6Elq3k,9118
62
- stubber/board/createstubs_min.py,sha256=1x0SpetEPuH8rnRkF9mE3qltevkKlA4tE9DySXkmwFM,13570
63
- stubber/board/createstubs_mpy.mpy,sha256=spYC-x1c2zOOzVz2n-2roqFCcMNNFwsDjUsKPFuCuKk,12236
59
+ stubber/board/createstubs_mem.py,sha256=3uewT8Nr2ba3vUJzjwNwK8DnHA0bSu7pY8yNMVJownQ,28755
60
+ stubber/board/createstubs_mem_min.py,sha256=9eUXrJu_kUPvyRU1ceah_WHIz76Jr4XeJ4OlCR0rzgk,11019
61
+ stubber/board/createstubs_mem_mpy.mpy,sha256=XeprD_VBohq9mHJWMpQAwu8LlbgSoFcCdTnDHhLBCrc,9118
62
+ stubber/board/createstubs_min.py,sha256=XkBIGgWIK7PeVJ-FhWK0Bsx-GRTJG5b6augb8y-uOLo,13699
63
+ stubber/board/createstubs_mpy.mpy,sha256=H5j-M9TXlVvaqOIN6ZG6k5oQ7TpLJE18ULXmV50Jdww,12388
64
64
  stubber/board/fw_info.py,sha256=6AQbN3jtQgllqWQYl4e-63KeEtV08EXk8_JnM6XBkvo,4554
65
65
  stubber/board/info.py,sha256=b7SOPZHVsVhaayKCwVkFZlYu0BW-UFI7LuG1Eop9480,5629
66
66
  stubber/board/main.py,sha256=f6V3tdt6sPZVLuwemT-NLuK9GySfW2c2J6PJMOOWQQw,413
67
- stubber/board/modulelist.txt,sha256=DUD4wbJ2YSOBkajklW6CFeoyUOwlVAs_Qc_-r3WXUW0,2780
67
+ stubber/board/modulelist.txt,sha256=f5WxcG8OBjwhZFDtvxllGDp-6bmH9M5A9knc_6YE7xI,2900
68
68
  stubber/board/pyrightconfig.json,sha256=6oHS4aDOfwKBAFeUPsCGJzEXpUgBZsPaF0M4P-N26D4,1376
69
69
  stubber/bulk/mcu_stubber.py,sha256=_1z0LUzcMbEIXIYInMJcAJZbBPTI8yCHgd1-1nlMscM,16379
70
70
  stubber/codemod/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -136,7 +136,7 @@ stubber/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
136
136
  stubber/tools/manifestfile.py,sha256=D5Plwj5LRDe6zq5m-ETKfum0vFAykka70WXSEHl83a4,23721
137
137
  stubber/tools/readme.md,sha256=kH7dA2Rs4BLCXa2ILoTDIj3sJHcGYtDPntyxVIOXvtI,199
138
138
  stubber/update_fallback.py,sha256=NUxp1sN1-8BLPd0rpExTcYBppUXYWPP8dOcjNeLY2Zo,4921
139
- stubber/update_module_list.py,sha256=QJ-c2K1Wf2SQdpMeGvlVabasKqsN9ZQV4ye5PbSpsWE,4640
139
+ stubber/update_module_list.py,sha256=1_dTr33KjJU3MAS5MP6R5S7YIYa2R1IBK4CWpmwusDc,4061
140
140
  stubber/utils/__init__.py,sha256=nV9FsOZsJ_hXsyUv4j0Qqp-PKycxyIktU9IoLs4kQmQ,225
141
141
  stubber/utils/config.py,sha256=Jg4eHhgKim4uP4IqZRWykRNiX1r-SXC2xSrbsVprGAA,4859
142
142
  stubber/utils/makeversionhdr.py,sha256=dO8sWLAY_ifT1IJJ1-JJ2z_thvfqJnK3c1_bHF_UI28,1953
@@ -147,8 +147,8 @@ stubber/utils/stubmaker.py,sha256=qld_Wfm9f4EuzedXlX1Ky0i0BJdR75oOOTha13_ekz0,52
147
147
  stubber/utils/typed_config_toml.py,sha256=ikifCIZGNhS_uqsfp6IwIpxdtZqbLtywprjWG_Q0y8o,2629
148
148
  stubber/utils/versions.py,sha256=4cGr-4Nbgqzoi-iJC08b_LFZH-CiyTNODlT-ihv4ZE0,3901
149
149
  stubber/variants.py,sha256=-o4TgotbKaCcYBdXkutPaBSR1JdxWmOAiuNT1UlahYc,3784
150
- micropython_stubber-1.20.2.dist-info/entry_points.txt,sha256=NQi_M36fgq5k6giSuASas3LrpF6CVdkzfvJC0ja73_g,55
151
- micropython_stubber-1.20.2.dist-info/LICENSE,sha256=Fx9qrL45ayRXgH6QzttboqZEjKXms0w1t_b_nkOqYCU,1572
152
- micropython_stubber-1.20.2.dist-info/METADATA,sha256=tOtMx82j-mRnlMlKbdPSSA_k-UWeJ6WXBbk92utyGdY,19107
153
- micropython_stubber-1.20.2.dist-info/WHEEL,sha256=d2fvjOD7sXsVzChCqf0Ty0JbHKBaLYwDbGQDwQTnJ50,88
154
- micropython_stubber-1.20.2.dist-info/RECORD,,
150
+ micropython_stubber-1.20.4.dist-info/entry_points.txt,sha256=NQi_M36fgq5k6giSuASas3LrpF6CVdkzfvJC0ja73_g,55
151
+ micropython_stubber-1.20.4.dist-info/LICENSE,sha256=Fx9qrL45ayRXgH6QzttboqZEjKXms0w1t_b_nkOqYCU,1572
152
+ micropython_stubber-1.20.4.dist-info/METADATA,sha256=Hb4UXiHcpXdCA8FG_v0cxH2m8zmSK-amlXIi31HewUQ,19158
153
+ micropython_stubber-1.20.4.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
154
+ micropython_stubber-1.20.4.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 1.7.0
2
+ Generator: poetry-core 1.9.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
@@ -5,8 +5,8 @@ Additional comands are added in the submodules.
5
5
 
6
6
  import rich_click as click
7
7
 
8
- from .config import config
9
- from .logger import make_quiet, set_loglevel
8
+ from .config import __version__, config
9
+ from .logger import log, make_quiet, set_loglevel
10
10
 
11
11
 
12
12
  def cb_verbose(ctx, param, value):
@@ -17,6 +17,7 @@ def cb_verbose(ctx, param, value):
17
17
  set_loglevel("TRACE")
18
18
  else:
19
19
  set_loglevel("DEBUG")
20
+ log.debug(f"version: {__version__}")
20
21
  else:
21
22
  set_loglevel("INFO")
22
23
  config.verbose = False
mpflash/mpflash/common.py CHANGED
@@ -47,7 +47,7 @@ class FWInfo:
47
47
  firmware: str = field(default="") # url or path to original firmware image
48
48
  variant: str = field(default="") # MicroPython variant
49
49
  preview: bool = field(default=False) # True if the firmware is a preview version
50
- version: str = field(default="") # MicroPython version
50
+ version: str = field(default="") # MicroPython version (NO v prefix)
51
51
  url: str = field(default="") # url to the firmware image download folder
52
52
  build: str = field(default="0") # The build = number of commits since the last release
53
53
  ext: str = field(default="") # the file extension of the firmware
mpflash/mpflash/config.py CHANGED
@@ -3,9 +3,18 @@
3
3
  from pathlib import Path
4
4
  from typing import List
5
5
 
6
+ import pkg_resources
6
7
  import platformdirs
7
8
 
8
9
 
10
+ def get_version():
11
+ name = __package__ or "mpflash"
12
+ try:
13
+ return pkg_resources.get_distribution(name).version
14
+ except pkg_resources.DistributionNotFound:
15
+ return "Package not found"
16
+
17
+
9
18
  class MPtoolConfig:
10
19
  """Centralized configuration for mpflash"""
11
20
 
@@ -19,3 +28,4 @@ class MPtoolConfig:
19
28
 
20
29
 
21
30
  config = MPtoolConfig()
31
+ __version__ = get_version()
@@ -19,8 +19,10 @@ from loguru import logger as log
19
19
  from rich.progress import track
20
20
 
21
21
  from mpflash.common import PORT_FWTYPES, FWInfo
22
+ from mpflash.downloaded import clean_downloaded_firmwares
22
23
  from mpflash.errors import MPFlashError
23
24
  from mpflash.mpboard_id import get_known_ports
25
+ from mpflash.vendor.versions import clean_version
24
26
 
25
27
  # avoid conflict with the ujson used by MicroPython
26
28
  jsonlines.ujson = None # type: ignore
@@ -32,8 +34,18 @@ MICROPYTHON_ORG_URL = "https://micropython.org/"
32
34
  # Regexes to remove dates and hashes in the filename that just get in the way
33
35
  RE_DATE = r"(-\d{8}-)"
34
36
  RE_HASH = r"(.g[0-9a-f]+\.)"
35
- # regex to extract the version from the firmware filename
36
- RE_VERSION_PREVIEW = r"(\d+\.\d+(\.\d+)?(-\w+.\d+)?)"
37
+ # regex to extract the version and the build from the firmware filename
38
+ # group 1 is the version, group 2 is the build
39
+ RE_VERSION_PREVIEW = r"v([\d\.]+)-?(?:preview\.)?(\d+)?\."
40
+ # 'RPI_PICO_W-v1.23.uf2'
41
+ # 'RPI_PICO_W-v1.23.0.uf2'
42
+ # 'RPI_PICO_W-v1.23.0-406.uf2'
43
+ # 'RPI_PICO_W-v1.23.0-preview.406.uf2'
44
+ # 'RPI_PICO_W-v1.23.0-preview.4.uf2'
45
+ # 'RPI_PICO_W-v1.23.0.uf2'
46
+ # 'https://micropython.org/resources/firmware/RPI_PICO_W-20240531-v1.24.0-preview.10.gc1a6b95bf.uf2'
47
+ # 'https://micropython.org/resources/firmware/RPI_PICO_W-20240531-v1.24.0-preview.10.uf2'
48
+ # 'RPI_PICO_W-v1.24.0-preview.10.gc1a6b95bf.uf2'
37
49
 
38
50
 
39
51
  # use functools.lru_cache to avoid needing to download pages multiple times
@@ -98,6 +110,7 @@ def board_firmware_urls(board_url: str, base_url: str, ext: str) -> List[str]:
98
110
  # The first run takes ~60 seconds to run for 4 ports , all boards
99
111
  # so it makes sense to cache the results and skip boards as soon as possible
100
112
  def get_boards(ports: List[str], boards: List[str], clean: bool) -> List[FWInfo]:
113
+ # sourcery skip: use-getitem-for-re-match-groups
101
114
  """
102
115
  Retrieves a list of firmware information for the specified ports and boards.
103
116
 
@@ -146,13 +159,15 @@ def get_boards(ports: List[str], boards: List[str], clean: bool) -> List[FWInfo]
146
159
  # board["firmware"] = _url
147
160
  # board["preview"] = "preview" in _url # type: ignore
148
161
  if ver_match := re.search(RE_VERSION_PREVIEW, _url):
149
- fw_info.version = ver_match[1]
162
+ fw_info.version = clean_version(ver_match.group(1))
163
+ fw_info.build = ver_match.group(2) or "0"
164
+ fw_info.preview = fw_info.build != "0"
165
+ # # else:
166
+ # # board.$1= ""
167
+ # if "preview." in fw_info.version:
168
+ # fw_info.build = fw_info.version.split("preview.")[-1]
150
169
  # else:
151
- # board.$1= ""
152
- if "preview." in fw_info.version:
153
- fw_info.build = fw_info.version.split("preview.")[-1]
154
- else:
155
- fw_info.build = "0"
170
+ # fw_info.build = "0"
156
171
 
157
172
  fw_info.ext = Path(fw_info.firmware).suffix
158
173
  fw_info.variant = fw_info.filename.split("-v")[0] if "-v" in fw_info.filename else ""
@@ -180,9 +195,21 @@ def download_firmwares(
180
195
  force: bool = False,
181
196
  clean: bool = True,
182
197
  ) -> int:
198
+ """
199
+ Downloads firmware files based on the specified firmware folder, ports, boards, versions, force flag, and clean flag.
200
+
201
+ Args:
202
+ firmware_folder : The folder to save the downloaded firmware files.
203
+ ports : The list of ports to check for firmware.
204
+ boards : The list of boards to download firmware for.
205
+ versions : The list of versions to download firmware for.
206
+ force : A flag indicating whether to force the download even if the firmware file already exists.
207
+ clean : A flag indicating to clean the date from the firmware filename.
208
+ """
183
209
  skipped = downloaded = 0
184
- if versions is None:
185
- versions = []
210
+ versions = [] if versions is None else [clean_version(v) for v in versions]
211
+ # handle renamed boards
212
+ boards = add_renamed_boards(boards)
186
213
 
187
214
  unique_boards = get_firmware_list(ports, boards, versions, clean)
188
215
 
@@ -191,6 +218,11 @@ def download_firmwares(
191
218
  # relevant
192
219
 
193
220
  log.info(f"Found {len(unique_boards)} relevant unique firmwares")
221
+ if not unique_boards:
222
+ log.error("No relevant firmwares could be found on https://micropython.org/download")
223
+ log.info(f"{versions=} {ports=} {boards=}")
224
+ log.info("Please check the website for the latest firmware files or try the preview version.")
225
+ return 0
194
226
 
195
227
  firmware_folder.mkdir(exist_ok=True)
196
228
 
@@ -214,7 +246,9 @@ def download_firmwares(
214
246
  continue
215
247
  writer.write(board.to_dict())
216
248
  downloaded += 1
217
- log.info(f"Downloaded {downloaded} firmwares, skipped {skipped} existing files.")
249
+ if downloaded > 0:
250
+ clean_downloaded_firmwares(firmware_folder)
251
+ log.success(f"Downloaded {downloaded} firmwares, skipped {skipped} existing files.")
218
252
  return downloaded + skipped
219
253
 
220
254
 
@@ -238,12 +272,15 @@ def get_firmware_list(ports: List[str], boards: List[str], versions: List[str],
238
272
  board_urls = sorted(get_boards(ports, boards, clean), key=key_fw_ver_pre_ext_bld)
239
273
 
240
274
  log.debug(f"Total {len(board_urls)} firmwares")
275
+
241
276
  relevant = [
242
277
  board
243
278
  for board in board_urls
244
- if board.board in boards and (board.version in versions or board.preview and preview)
245
- # and b["port"] in ["esp32", "rp2"]
279
+ if board.version in versions and board.build == "0" and board.board in boards and not board.preview
246
280
  ]
281
+
282
+ if preview:
283
+ relevant.extend([board for board in board_urls if board.board in boards and board.preview])
247
284
  log.debug(f"Matching firmwares: {len(relevant)}")
248
285
  # select the unique boards
249
286
  unique_boards: List[FWInfo] = []
@@ -272,7 +309,7 @@ def download(
272
309
  boards : The list of boards to download firmware for.
273
310
  versions : The list of versions to download firmware for.
274
311
  force : A flag indicating whether to force the download even if the firmware file already exists.
275
- clean : A flag indicating whether to perform a clean download.
312
+ clean : A flag indicating whether to clean the date from the firmware filename.
276
313
 
277
314
  Returns:
278
315
  int: The number of downloaded firmware files.
@@ -284,11 +321,41 @@ def download(
284
321
  if not boards:
285
322
  log.critical("No boards found, please connect a board or specify boards to download firmware for.")
286
323
  raise MPFlashError("No boards found")
287
- # versions = [clean_version(v, drop_v=True) for v in versions] # remove leading v from version
324
+
288
325
  try:
289
326
  destination.mkdir(exist_ok=True, parents=True)
290
327
  except (PermissionError, FileNotFoundError) as e:
291
328
  log.critical(f"Could not create folder {destination}")
292
329
  raise MPFlashError(f"Could not create folder {destination}") from e
330
+ try:
331
+ result = download_firmwares(destination, ports, boards, versions, force=force, clean=clean)
332
+ except requests.exceptions.RequestException as e:
333
+ log.exception(e)
334
+ raise MPFlashError("Could not connect to micropython.org") from e
335
+
336
+ return result
337
+
338
+
339
+ def add_renamed_boards(boards: List[str]) -> List[str]:
340
+ """
341
+ Adds the renamed boards to the list of boards.
293
342
 
294
- return download_firmwares(destination, ports, boards, versions, force=force, clean=clean)
343
+ Args:
344
+ boards : The list of boards to add the renamed boards to.
345
+
346
+ Returns:
347
+ List[str]: The list of boards with the renamed boards added.
348
+
349
+ """
350
+ renamed = {
351
+ "PICO": ["RPI_PICO"],
352
+ "PICO_W": ["RPI_PICO_W"],
353
+ "GENERIC": ["ESP32_GENERIC", "ESP8266_GENERIC"], # just add both of them
354
+ }
355
+ _boards = boards.copy()
356
+ for board in boards:
357
+ if board in renamed and renamed[board] not in boards:
358
+ _boards.extend(renamed[board])
359
+ if board != board.upper() and board.upper() not in boards:
360
+ _boards.append(board.upper())
361
+ return _boards
@@ -24,10 +24,26 @@ def downloaded_firmwares(fw_folder: Path) -> List[FWInfo]:
24
24
  return firmwares
25
25
 
26
26
 
27
+ def clean_downloaded_firmwares(fw_folder: Path) -> None:
28
+ """
29
+ Remove duplicate entries from the firmware.jsonl file, keeping the latest one
30
+ uniqueness is based on the filename
31
+ """
32
+ firmwares = downloaded_firmwares(fw_folder)
33
+ if not firmwares:
34
+ return
35
+ # keep the latest entry
36
+ unique_fw = {fw.filename: fw for fw in firmwares}
37
+ with jsonlines.open(fw_folder / "firmware.jsonl", "w") as writer:
38
+ for fw in unique_fw.values():
39
+ writer.write(fw.to_dict())
40
+ log.info(f"Removed duplicate entries from firmware.jsonl in {fw_folder}")
41
+
42
+
27
43
  def find_downloaded_firmware(
28
44
  *,
29
45
  board_id: str,
30
- version: str = "",
46
+ version: str = "", # v1.2.3
31
47
  port: str = "",
32
48
  variants: bool = False,
33
49
  fw_folder: Optional[Path] = None,
@@ -38,21 +54,22 @@ def find_downloaded_firmware(
38
54
  selector = {}
39
55
  fw_folder = fw_folder or config.firmware_folder
40
56
  # Use the information in firmwares.jsonl to find the firmware file
57
+ log.debug(f"{trie}] Looking for firmware for {board_id} {version} ")
41
58
  fw_list = downloaded_firmwares(fw_folder)
42
59
  if not fw_list:
43
60
  log.error("No firmware files found. Please download the firmware first.")
44
61
  return []
45
62
  # filter by version
46
- version = clean_version(version, drop_v=True)
63
+ version = clean_version(version)
47
64
  fw_list = filter_downloaded_fwlist(fw_list, board_id, version, port, variants, selector)
48
65
 
49
66
  if not fw_list and trie < 3:
50
67
  log.info(f"Try ({trie+1}) to find a firmware for the board {board_id}")
51
68
  if trie == 1:
52
- # ESP board naming conventions have changed by adding a PORT refix
69
+ # ESP board naming conventions have changed by adding a PORT prefix
53
70
  if port.startswith("esp") and not board_id.startswith(port.upper()):
54
71
  board_id = f"{port.upper()}_{board_id}"
55
- # RP2 board naming conventions have changed by adding a _RPIprefix
72
+ # RP2 board naming conventions have changed by adding a _RPI prefix
56
73
  if port == "rp2" and not board_id.startswith("RPI_"):
57
74
  board_id = f"RPI_{board_id}"
58
75
  elif trie == 2:
@@ -75,7 +92,7 @@ def find_downloaded_firmware(
75
92
  def filter_downloaded_fwlist(
76
93
  fw_list: List[FWInfo],
77
94
  board_id: str,
78
- version: str,
95
+ version: str, # v1.2.3
79
96
  port: str,
80
97
  # preview: bool,
81
98
  variants: bool,
@@ -86,11 +103,14 @@ def filter_downloaded_fwlist(
86
103
  # never get a preview for an older version
87
104
  fw_list = [fw for fw in fw_list if fw.preview]
88
105
  else:
89
- fw_list = [fw for fw in fw_list if fw.version == version]
90
-
106
+ # FWInfo version has no v1.2.3 prefix
107
+ _version = {clean_version(version, drop_v=True), clean_version(version, drop_v=False)}
108
+ fw_list = [fw for fw in fw_list if fw.version in _version]
109
+ log.trace(f"Filtering firmware for {version} : {len(fw_list)} found.")
91
110
  # filter by port
92
111
  if port:
93
112
  fw_list = [fw for fw in fw_list if fw.port == port]
113
+ log.trace(f"Filtering firmware for {port} : {len(fw_list)} found.")
94
114
 
95
115
  if board_id:
96
116
  if variants:
@@ -99,6 +119,7 @@ def filter_downloaded_fwlist(
99
119
  else:
100
120
  # the firmware variant should match exactly the board_id
101
121
  fw_list = [fw for fw in fw_list if fw.variant == board_id]
122
+ log.trace(f"Filtering firmware for {board_id} : {len(fw_list)} found.")
102
123
  if selector and port in selector:
103
124
  fw_list = [fw for fw in fw_list if fw.filename.endswith(selector[port])]
104
125
  return fw_list
@@ -14,7 +14,7 @@ from rich.progress import track
14
14
  from mpflash.mpremoteboard import MPRemoteBoard
15
15
 
16
16
  from .common import PORT_FWTYPES
17
- from .config import config
17
+ from .flash_uf2_boardid import get_board_id
18
18
  from .flash_uf2_linux import dismount_uf2_linux, wait_for_UF2_linux
19
19
  from .flash_uf2_macos import wait_for_UF2_macos
20
20
  from .flash_uf2_windows import wait_for_UF2_windows
@@ -45,11 +45,7 @@ def flash_uf2(mcu: MPRemoteBoard, fw_file: Path, erase: bool) -> Optional[MPRemo
45
45
  destination = wait_for_UF2_windows()
46
46
  elif sys.platform == "darwin":
47
47
  log.warning(f"OS {sys.platform} not tested/supported")
48
- # TODO: test which of the options is best
49
- if "macos_uf2" in config.tests:
50
- destination = wait_for_UF2_macos()
51
- else:
52
- destination = wait_for_UF2_linux()
48
+ destination = wait_for_UF2_macos()
53
49
  else:
54
50
  log.warning(f"OS {sys.platform} not tested/supported")
55
51
  return None
@@ -59,6 +55,8 @@ def flash_uf2(mcu: MPRemoteBoard, fw_file: Path, erase: bool) -> Optional[MPRemo
59
55
  return None
60
56
 
61
57
  log.info("Board is in bootloader mode")
58
+ board_id = get_board_id(destination) # type: ignore
59
+ log.info(f"Board ID: {board_id}")
62
60
  log.info(f"Copying {fw_file} to {destination}.")
63
61
  shutil.copy(fw_file, destination)
64
62
  log.success("Done copying, resetting the board and wait for it to restart")
@@ -1,4 +1,5 @@
1
1
  from pathlib import Path
2
+
2
3
  from loguru import logger as log
3
4
 
4
5
 
@@ -10,5 +11,5 @@ def get_board_id(path: Path):
10
11
  for line in data:
11
12
  if line.startswith("Board-ID"):
12
13
  board_id = line[9:].strip()
13
- log.trace(f"Found Board-ID={board_id}")
14
+ log.debug(f"INFO_UF2.TXT Board-ID={board_id}")
14
15
  return board_id
@@ -6,73 +6,32 @@ from __future__ import annotations
6
6
  import sys
7
7
  import time
8
8
  from pathlib import Path
9
+ from typing import Optional
9
10
 
10
11
  from loguru import logger as log
11
12
  from rich.progress import track
12
13
 
13
14
  from .flash_uf2_boardid import get_board_id
14
- from .uf2disk import UF2Disk
15
15
 
16
16
 
17
- def get_uf2_drives():
18
- """
19
- Get a list of all the (un)mounted UF2 drives
20
- """
21
- if sys.platform != "linux":
22
- log.error("pumount only works on Linux")
23
- return
24
- # import blkinfo only on linux
25
- from blkinfo import BlkDiskInfo
26
-
27
- myblkd = BlkDiskInfo()
28
- filters = {
29
- "tran": "usb",
30
- }
31
- usb_disks = myblkd.get_disks(filters)
32
- for disk in usb_disks:
33
- if disk["fstype"] == "vfat":
34
- uf2_part = disk
35
- # unpartioned usb disk or partition (e.g. /dev/sdb )
36
- # SEEED WIO Terminal is unpartioned
37
- # print( json.dumps(uf2_part, indent=4))
38
- uf2 = UF2Disk()
39
- uf2.device_path = "/dev/" + uf2_part["name"]
40
- uf2.label = uf2_part["label"]
41
- uf2.mountpoint = uf2_part["mountpoint"]
42
- yield uf2
43
- elif disk["type"] == "disk" and disk.get("children") and len(disk.get("children")) > 0:
44
- if disk.get("children")[0]["type"] == "part" and disk.get("children")[0]["fstype"] == "vfat":
45
- uf2_part = disk.get("children")[0]
46
- # print( json.dumps(uf2_part, indent=4))
47
- uf2 = UF2Disk()
48
- uf2.device_path = "/dev/" + uf2_part["name"]
49
- uf2.label = uf2_part["label"]
50
- uf2.mountpoint = uf2_part["mountpoint"]
51
- yield uf2
52
-
53
-
54
- def wait_for_UF2_macos(s_max: int = 10):
55
- destination = ""
56
- wait = 10
57
- uf2_drives = []
58
- # while not destination and wait > 0:
17
+ def wait_for_UF2_macos(s_max: int = 10) -> Optional[Path]:
18
+ """Wait for the MCU to mount as a drive"""
19
+ if s_max < 1:
20
+ s_max = 10
21
+ destination = None
59
22
  for _ in track(
60
23
  range(s_max), description="Waiting for mcu to mount as a drive", transient=True, refresh_per_second=2
61
24
  ):
62
- # log.info(f"Waiting for mcu to mount as a drive : {wait} seconds left")
63
- uf2_drives += list(get_uf2_drives())
64
- for drive in get_uf2_drives():
65
- time.sleep(1)
25
+ # log.info(f"Waiting for mcu to mount as a drive : {n} seconds left")
26
+ vol_mounts = Path("/Volumes").iterdir()
27
+ for vol in vol_mounts:
66
28
  try:
67
- if Path(drive.mountpoint, "INFO_UF2.TXT").exists():
68
- board_id = get_board_id(Path(drive.mountpoint)) # type: ignore
69
- destination = Path(drive.mountpoint)
29
+ if Path(vol, "INFO_UF2.TXT").exists():
30
+ destination = Path(vol)
70
31
  break
71
- except PermissionError:
72
- log.debug(f"Permission error on {drive.mountpoint}")
73
- continue
32
+ except OSError:
33
+ pass
74
34
  if destination:
75
35
  break
76
36
  time.sleep(1)
77
- wait -= 1
78
37
  return destination
@@ -5,25 +5,25 @@ from __future__ import annotations
5
5
 
6
6
  import time
7
7
  from pathlib import Path
8
+ from typing import Optional
8
9
 
9
10
  import psutil
10
11
  from rich.progress import track
11
12
 
12
- from .flash_uf2_boardid import get_board_id
13
13
 
14
14
 
15
- def wait_for_UF2_windows(s_max: int = 10):
15
+
16
+ def wait_for_UF2_windows(s_max: int = 10) -> Optional[Path]:
16
17
  """Wait for the MCU to mount as a drive"""
17
18
  if s_max < 1:
18
19
  s_max = 10
19
- destination = ""
20
+ destination = None
20
21
  for _ in track(range(s_max), description="Waiting for mcu to mount as a drive", transient=True,refresh_per_second=2):
21
22
  # log.info(f"Waiting for mcu to mount as a drive : {n} seconds left")
22
23
  drives = [drive.device for drive in psutil.disk_partitions()]
23
24
  for drive in drives:
24
25
  try:
25
26
  if Path(drive, "INFO_UF2.TXT").exists():
26
- board_id = get_board_id(Path(drive)) # type: ignore
27
27
  destination = Path(drive)
28
28
  break
29
29
  except OSError:
@@ -77,10 +77,14 @@ def known_stored_boards(port: str, versions: Optional[List[str]] = None) -> List
77
77
  @lru_cache(maxsize=20)
78
78
  def find_known_board(board_id: str) -> Board:
79
79
  """Find the board for the given BOARD_ID or 'board description' and return the board info as a Board object"""
80
+ # FIXME : functional overlap with:
81
+ # mpboard_id\board_id.py _find_board_id_by_description
80
82
  info = read_known_boardinfo()
81
83
  for board_info in info:
82
84
  if board_id in (board_info.board_id, board_info.description):
83
85
  if not board_info.cpu:
86
+ # safeguard for older board_info.json files
87
+ print(f"Board {board_id} has no CPU info, using port as CPU")
84
88
  if " with " in board_info.description:
85
89
  board_info.cpu = board_info.description.split(" with ")[-1]
86
90
  else:
@@ -44,7 +44,23 @@ def _find_board_id_by_description(
44
44
  """
45
45
  Find the MicroPython BOARD_ID based on the description in the firmware
46
46
  using the pre-built board_info.json file
47
+
48
+ Parameters:
49
+ descr: str
50
+ Description of the board
51
+ short_descr: str
52
+ Short description of the board (optional)
53
+ version: str
54
+ Version of the MicroPython firmware
55
+ board_info: Path
56
+ Path to the board_info.json file (optional)
57
+
47
58
  """
59
+ # FIXME: functional overlap with
60
+ # src\mpflash\mpflash\mpboard_id\__init__.py find_known_board
61
+
62
+ if not short_descr and " with " in descr:
63
+ short_descr = descr.split(" with ")[0]
48
64
 
49
65
  candidate_boards = read_known_boardinfo(board_info)
50
66
 
@@ -58,10 +74,10 @@ def _find_board_id_by_description(
58
74
  # FIXME if latest stable is newer than the last version in the boardlist this will fail
59
75
  log.trace(f"Version {version} not found in board info, using latest known version {known_versions[-1]}")
60
76
  version = known_versions[-1]
61
- version_matches = [b for b in candidate_boards if b.version.startswith(version)]
62
- if not version_matches:
77
+ if version_matches := [b for b in candidate_boards if b.version.startswith(version)]:
78
+ candidate_boards = version_matches
79
+ else:
63
80
  raise MPFlashError(f"No board info found for version {version}")
64
- candidate_boards = version_matches
65
81
  matches = [b for b in candidate_boards if b.description == descr]
66
82
  if not matches and short_descr:
67
83
  matches = [b for b in candidate_boards if b.description == short_descr]
@@ -13,10 +13,11 @@ HERE = Path(__file__).parent
13
13
 
14
14
 
15
15
  def write_boardinfo_json(board_list: List[Board], *, folder: Path):
16
- """Writes the board information to JSON and CSV files.
16
+ """Writes the board information to a JSON file.
17
17
 
18
18
  Args:
19
19
  board_list (List[Board]): The list of Board objects.
20
+ folder (Path): The folder where the compressed JSON file will be saved.
20
21
  """
21
22
  import zipfile
22
23
 
mpflash/pyproject.toml CHANGED
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "mpflash"
3
- version = "0.8.0"
3
+ version = "0.8.3"
4
4
  description = "Flash and download tool for MicroPython firmwares"
5
5
  authors = ["Jos Verlinde <jos_verlinde@hotmail.com>"]
6
6
  license = "MIT"
stubber/__init__.py CHANGED
@@ -1,3 +1,3 @@
1
1
  """get the version"""
2
2
 
3
- __version__ = "1.20.2"
3
+ __version__ = "1.20.4"
@@ -24,7 +24,7 @@ try:
24
24
  except ImportError:
25
25
  from ucollections import OrderedDict # type: ignore
26
26
 
27
- __version__ = "v1.20.2"
27
+ __version__ = "v1.20.4"
28
28
  ENOENT = 2
29
29
  _MAX_CLASS_LEVEL = 2 # Max class nesting
30
30
  LIBS = ["lib", "/lib", "/sd/lib", "/flash/lib", "."]
@@ -596,10 +596,10 @@ def _info(): # type:() -> dict[str, str]
596
596
  if (
597
597
  info["version"]
598
598
  and info["version"].endswith(".0")
599
- and info["version"] >= "1.10.0" # versions from 1.10.0 to 1.20.2 do not have a micro .0
599
+ and info["version"] >= "1.10.0" # versions from 1.10.0 to 1.20.4 do not have a micro .0
600
600
  and info["version"] <= "1.19.9"
601
601
  ):
602
- # versions from 1.10.0 to 1.20.2 do not have a micro .0
602
+ # versions from 1.10.0 to 1.20.4 do not have a micro .0
603
603
  info["version"] = info["version"][:-2]
604
604
 
605
605
  # spell-checker: disable
@@ -838,6 +838,8 @@ def main():
838
838
  "interstate75",
839
839
  "io",
840
840
  "jpegdec",
841
+ "js",
842
+ "jsffi",
841
843
  "json",
842
844
  "lcd160cr",
843
845
  "lodepng",
@@ -863,6 +865,7 @@ def main():
863
865
  "network",
864
866
  "ntptime",
865
867
  "onewire",
868
+ "openamp",
866
869
  "os",
867
870
  "pcf85063a",
868
871
  "picoexplorer",
@@ -941,6 +944,12 @@ def main():
941
944
  "ure",
942
945
  "urequests",
943
946
  "urllib/urequest",
947
+ "usb/device",
948
+ "usb/device/cdc",
949
+ "usb/device/hid",
950
+ "usb/device/keyboard",
951
+ "usb/device/midi",
952
+ "usb/device/mouse",
944
953
  "uselect",
945
954
  "usocket",
946
955
  "ussl",
@@ -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.20.2
21
+ This variant was generated from createstubs.py by micropython-stubber v1.20.4
22
22
  """
23
23
 
24
24
  # Copyright (c) 2019-2024 Jos Verlinde
@@ -43,7 +43,7 @@ try:
43
43
  except ImportError:
44
44
  from ucollections import OrderedDict # type: ignore
45
45
 
46
- __version__ = "v1.20.2"
46
+ __version__ = "v1.20.4"
47
47
  ENOENT = 2
48
48
  _MAX_CLASS_LEVEL = 2 # Max class nesting
49
49
  LIBS = ["lib", "/lib", "/sd/lib", "/flash/lib", "."]
@@ -607,10 +607,10 @@ def _info(): # type:() -> dict[str, str]
607
607
  if (
608
608
  info["version"]
609
609
  and info["version"].endswith(".0")
610
- and info["version"] >= "1.10.0" # versions from 1.10.0 to 1.20.2 do not have a micro .0
610
+ and info["version"] >= "1.10.0" # versions from 1.10.0 to 1.20.4 do not have a micro .0
611
611
  and info["version"] <= "1.19.9"
612
612
  ):
613
- # versions from 1.10.0 to 1.20.2 do not have a micro .0
613
+ # versions from 1.10.0 to 1.20.4 do not have a micro .0
614
614
  info["version"] = info["version"][:-2]
615
615
 
616
616
  # spell-checker: disable
@@ -51,7 +51,7 @@ try:from machine import reset
51
51
  except O:pass
52
52
  try:from collections import OrderedDict as l
53
53
  except O:from ucollections import OrderedDict as l
54
- __version__='v1.20.2'
54
+ __version__='v1.20.4'
55
55
  A3=2
56
56
  A4=2
57
57
  A5=['lib','/lib','/sd/lib','/flash/lib',J]
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.20.2
12
+ This variant was generated from createstubs.py by micropython-stubber v1.20.4
13
13
  """
14
14
 
15
15
  # Copyright (c) 2019-2024 Jos Verlinde
@@ -34,7 +34,7 @@ try:
34
34
  except ImportError:
35
35
  from ucollections import OrderedDict # type: ignore
36
36
 
37
- __version__ = "v1.20.2"
37
+ __version__ = "v1.20.4"
38
38
  ENOENT = 2
39
39
  _MAX_CLASS_LEVEL = 2 # Max class nesting
40
40
  LIBS = ["lib", "/lib", "/sd/lib", "/flash/lib", "."]
@@ -598,10 +598,10 @@ def _info(): # type:() -> dict[str, str]
598
598
  if (
599
599
  info["version"]
600
600
  and info["version"].endswith(".0")
601
- and info["version"] >= "1.10.0" # versions from 1.10.0 to 1.20.2 do not have a micro .0
601
+ and info["version"] >= "1.10.0" # versions from 1.10.0 to 1.20.4 do not have a micro .0
602
602
  and info["version"] <= "1.19.9"
603
603
  ):
604
- # versions from 1.10.0 to 1.20.2 do not have a micro .0
604
+ # versions from 1.10.0 to 1.20.4 do not have a micro .0
605
605
  info["version"] = info["version"][:-2]
606
606
 
607
607
  # spell-checker: disable
@@ -47,7 +47,7 @@ try:from machine import reset
47
47
  except N:pass
48
48
  try:from collections import OrderedDict as g
49
49
  except N:from ucollections import OrderedDict as g
50
- __version__='v1.20.2'
50
+ __version__='v1.20.4'
51
51
  y=2
52
52
  z=2
53
53
  A0=['lib','/lib','/sd/lib','/flash/lib',J]
Binary file
@@ -50,7 +50,7 @@ try:from machine import reset
50
50
  except N:pass
51
51
  try:from collections import OrderedDict as h
52
52
  except N:from ucollections import OrderedDict as h
53
- __version__='v1.20.2'
53
+ __version__='v1.20.4'
54
54
  A0=2
55
55
  A1=2
56
56
  A5=['lib','/lib','/sd/lib','/flash/lib',J]
@@ -287,7 +287,7 @@ def read_path():
287
287
  def j():
288
288
  try:A=bytes('abc',encoding='utf8');B=j.__module__;return H
289
289
  except(k,I):return U
290
- def main():stubber=Stubber(path=read_path());stubber.clean();stubber.modules=['WM8960','_OTA','_asyncio','_boot_fat','_coap','_espnow','_flash_control_OTA','_main_pybytes','_mqtt','_mqtt_core','_msg_handl','_onewire','_periodical_pin','_pybytes','_pybytes_ca','_pybytes_config','_pybytes_config_reader','_pybytes_connection','_pybytes_constants','_pybytes_debug','_pybytes_library','_pybytes_machine_learning','_pybytes_main','_pybytes_protocol','_pybytes_pyconfig','_pybytes_pymesh_config','_rp2','_terminal','_thread','_uasyncio','_urequest','adcfft','aioble/__init__','aioble/central','aioble/client','aioble/core','aioble/device','aioble/l2cap','aioble/peripheral','aioble/security','aioble/server','aioespnow','ak8963','apa102','apa106','argparse','array','asyncio/__init__','asyncio/core','asyncio/event','asyncio/funcs','asyncio/lock','asyncio/stream','binascii','bluetooth','breakout_as7262','breakout_bh1745','breakout_bme280','breakout_bme68x','breakout_bmp280','breakout_dotmatrix','breakout_encoder','breakout_icp10125','breakout_ioexpander','breakout_ltr559','breakout_matrix11x7','breakout_mics6814','breakout_msa301','breakout_paa5100','breakout_pmw3901','breakout_potentiometer','breakout_rgbmatrix5x5','breakout_rtc','breakout_scd41','breakout_sgp30','breakout_trackball','breakout_vl53l5cx','btree','cmath','collections','crypto','cryptolib','curl','deflate','dht','display','display_driver_utils','ds18x20','encoder','errno','esp','esp32','espidf','espnow','ffi','flashbdev','framebuf','freesans20','fs_driver','functools','galactic','gc','gfx_pack','gsm','hashlib','heapq','hub75','ili9341','ili9XXX','imagetools','inisetup','interstate75','io','jpegdec','json','lcd160cr','lodepng',w,'lsm6dsox','lv_colors','lv_utils','lvgl','lwip','machine','math','microWebSocket','microWebSrv','microWebTemplate',b,'mip','mip/__init__','mip/__main__','motor','mpu6500','mpu9250','neopixel','network','ntptime','onewire','os','pcf85063a','picoexplorer','picographics','picokeypad','picoscroll','picounicorn','picowireless','pimoroni','pimoroni_bus','pimoroni_i2c','plasma','platform','pyb',g,'pye','qrcode','queue','random','requests','requests/__init__','rp2','rtch','samd','select','servo','socket','ssd1306','ssh','ssl','stm','struct',v,'termios','time','tls','tpcalib','uarray','uasyncio/__init__','uasyncio/core','uasyncio/event','uasyncio/funcs','uasyncio/lock','uasyncio/stream','uasyncio/tasks','ubinascii','ubluetooth','ucollections','ucrypto','ucryptolib','uctypes','uerrno','uftpd','uhashlib','uheapq','uio','ujson','ulab','ulab/approx','ulab/compare','ulab/fft','ulab/filter','ulab/linalg','ulab/numerical','ulab/poly','ulab/user','ulab/vector','umachine','umqtt/__init__','umqtt/robust','umqtt/simple','uos','uplatform','uqueue','urandom','ure','urequests','urllib/urequest','uselect','usocket','ussl','ustruct','usys','utelnetserver','utime','utimeq','uwebsocket','uzlib',C,'vfs','websocket','websocket_helper','wipy','writer','xpt2046','ymodem','zephyr','zlib'];F.collect();stubber.create_all_stubs()
290
+ def main():stubber=Stubber(path=read_path());stubber.clean();stubber.modules=['WM8960','_OTA','_asyncio','_boot_fat','_coap','_espnow','_flash_control_OTA','_main_pybytes','_mqtt','_mqtt_core','_msg_handl','_onewire','_periodical_pin','_pybytes','_pybytes_ca','_pybytes_config','_pybytes_config_reader','_pybytes_connection','_pybytes_constants','_pybytes_debug','_pybytes_library','_pybytes_machine_learning','_pybytes_main','_pybytes_protocol','_pybytes_pyconfig','_pybytes_pymesh_config','_rp2','_terminal','_thread','_uasyncio','_urequest','adcfft','aioble/__init__','aioble/central','aioble/client','aioble/core','aioble/device','aioble/l2cap','aioble/peripheral','aioble/security','aioble/server','aioespnow','ak8963','apa102','apa106','argparse','array','asyncio/__init__','asyncio/core','asyncio/event','asyncio/funcs','asyncio/lock','asyncio/stream','binascii','bluetooth','breakout_as7262','breakout_bh1745','breakout_bme280','breakout_bme68x','breakout_bmp280','breakout_dotmatrix','breakout_encoder','breakout_icp10125','breakout_ioexpander','breakout_ltr559','breakout_matrix11x7','breakout_mics6814','breakout_msa301','breakout_paa5100','breakout_pmw3901','breakout_potentiometer','breakout_rgbmatrix5x5','breakout_rtc','breakout_scd41','breakout_sgp30','breakout_trackball','breakout_vl53l5cx','btree','cmath','collections','crypto','cryptolib','curl','deflate','dht','display','display_driver_utils','ds18x20','encoder','errno','esp','esp32','espidf','espnow','ffi','flashbdev','framebuf','freesans20','fs_driver','functools','galactic','gc','gfx_pack','gsm','hashlib','heapq','hub75','ili9341','ili9XXX','imagetools','inisetup','interstate75','io','jpegdec','js','jsffi','json','lcd160cr','lodepng',w,'lsm6dsox','lv_colors','lv_utils','lvgl','lwip','machine','math','microWebSocket','microWebSrv','microWebTemplate',b,'mip','mip/__init__','mip/__main__','motor','mpu6500','mpu9250','neopixel','network','ntptime','onewire','openamp','os','pcf85063a','picoexplorer','picographics','picokeypad','picoscroll','picounicorn','picowireless','pimoroni','pimoroni_bus','pimoroni_i2c','plasma','platform','pyb',g,'pye','qrcode','queue','random','requests','requests/__init__','rp2','rtch','samd','select','servo','socket','ssd1306','ssh','ssl','stm','struct',v,'termios','time','tls','tpcalib','uarray','uasyncio/__init__','uasyncio/core','uasyncio/event','uasyncio/funcs','uasyncio/lock','uasyncio/stream','uasyncio/tasks','ubinascii','ubluetooth','ucollections','ucrypto','ucryptolib','uctypes','uerrno','uftpd','uhashlib','uheapq','uio','ujson','ulab','ulab/approx','ulab/compare','ulab/fft','ulab/filter','ulab/linalg','ulab/numerical','ulab/poly','ulab/user','ulab/vector','umachine','umqtt/__init__','umqtt/robust','umqtt/simple','uos','uplatform','uqueue','urandom','ure','urequests','urllib/urequest','usb/device','usb/device/cdc','usb/device/hid','usb/device/keyboard','usb/device/midi','usb/device/mouse','uselect','usocket','ussl','ustruct','usys','utelnetserver','utime','utimeq','uwebsocket','uzlib',C,'vfs','websocket','websocket_helper','wipy','writer','xpt2046','ymodem','zephyr','zlib'];F.collect();stubber.create_all_stubs()
291
291
  if __name__=='__main__'or j():
292
292
  if not A4('no_auto_stubber.txt'):
293
293
  try:F.threshold(4*1024);F.enable()
Binary file
@@ -113,6 +113,8 @@ inisetup
113
113
  interstate75
114
114
  io
115
115
  jpegdec
116
+ js
117
+ jsffi
116
118
  json
117
119
  lcd160cr
118
120
  lodepng
@@ -138,6 +140,7 @@ neopixel
138
140
  network
139
141
  ntptime
140
142
  onewire
143
+ openamp
141
144
  os
142
145
  pcf85063a
143
146
  picoexplorer
@@ -216,6 +219,12 @@ urandom
216
219
  ure
217
220
  urequests
218
221
  urllib/urequest
222
+ usb/device
223
+ usb/device/cdc
224
+ usb/device/hid
225
+ usb/device/keyboard
226
+ usb/device/midi
227
+ usb/device/mouse
219
228
  uselect
220
229
  usocket
221
230
  ussl
@@ -12,8 +12,6 @@ for this :
12
12
  - board/createstubs.py
13
13
 
14
14
  - TODO: remove the frozen modules from this list
15
- - TODO: bump patch number if there are actual changes
16
-
17
15
  """
18
16
 
19
17
  from pathlib import Path
@@ -32,7 +30,7 @@ def read_modules(path: Optional[Path] = None) -> Set[str]:
32
30
  """
33
31
  path = Path(path or "./data")
34
32
  assert path
35
- all_modules = set()
33
+ all_modules: Set[str] = set()
36
34
  for file in path.glob("*.txt"):
37
35
  log.debug(f"processing: {file.name}")
38
36
  with file.open("r") as f:
@@ -45,27 +43,7 @@ def read_modules(path: Optional[Path] = None) -> Set[str]:
45
43
  file_mods = [m for m in file_mods if not m.endswith("_test")]
46
44
  all_modules = set(all_modules | set(file_mods))
47
45
  log.trace(">" * 40)
48
-
49
- return all_modules
50
-
51
-
52
- # def wrapped(modules: Union[Set, List]) -> str:
53
- # "wrap code line at spaces"
54
- # long_line = str(modules)
55
- # _wrapped = " self.modules = "
56
- # IDENT = len(_wrapped)
57
- # MAX_WIDTH = 135
58
-
59
- # # find seperator
60
- # while len(long_line) > MAX_WIDTH:
61
- # p1 = long_line.find("', ", MAX_WIDTH)
62
- # # drop space
63
- # p1 += 3
64
- # short = long_line[0 : p1 - 1]
65
- # _wrapped += short + "\n" + " " * IDENT
66
- # long_line = long_line[p1 - 1 :]
67
- # _wrapped += long_line
68
- # return _wrapped
46
+ return {m.replace(".", "/") for m in all_modules}
69
47
 
70
48
 
71
49
  def update_module_list():