micropython-stubber 1.23.1.post1__py3-none-any.whl → 1.23.2__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 (152) hide show
  1. {micropython_stubber-1.23.1.post1.dist-info → micropython_stubber-1.23.2.dist-info}/LICENSE +30 -30
  2. {micropython_stubber-1.23.1.post1.dist-info → micropython_stubber-1.23.2.dist-info}/METADATA +4 -4
  3. micropython_stubber-1.23.2.dist-info/RECORD +158 -0
  4. mpflash/README.md +220 -220
  5. mpflash/libusb_flash.ipynb +203 -203
  6. mpflash/mpflash/add_firmware.py +98 -98
  7. mpflash/mpflash/ask_input.py +236 -236
  8. mpflash/mpflash/basicgit.py +284 -284
  9. mpflash/mpflash/bootloader/__init__.py +2 -2
  10. mpflash/mpflash/bootloader/activate.py +60 -60
  11. mpflash/mpflash/bootloader/detect.py +82 -82
  12. mpflash/mpflash/bootloader/manual.py +101 -101
  13. mpflash/mpflash/bootloader/micropython.py +12 -12
  14. mpflash/mpflash/bootloader/touch1200.py +36 -36
  15. mpflash/mpflash/cli_download.py +129 -129
  16. mpflash/mpflash/cli_flash.py +224 -216
  17. mpflash/mpflash/cli_group.py +111 -111
  18. mpflash/mpflash/cli_list.py +87 -87
  19. mpflash/mpflash/cli_main.py +39 -39
  20. mpflash/mpflash/common.py +210 -166
  21. mpflash/mpflash/config.py +44 -44
  22. mpflash/mpflash/connected.py +96 -77
  23. mpflash/mpflash/download.py +364 -364
  24. mpflash/mpflash/downloaded.py +130 -130
  25. mpflash/mpflash/errors.py +9 -9
  26. mpflash/mpflash/flash/__init__.py +55 -55
  27. mpflash/mpflash/flash/esp.py +59 -59
  28. mpflash/mpflash/flash/stm32.py +19 -19
  29. mpflash/mpflash/flash/stm32_dfu.py +104 -104
  30. mpflash/mpflash/flash/uf2/__init__.py +88 -88
  31. mpflash/mpflash/flash/uf2/boardid.py +15 -15
  32. mpflash/mpflash/flash/uf2/linux.py +136 -130
  33. mpflash/mpflash/flash/uf2/macos.py +42 -42
  34. mpflash/mpflash/flash/uf2/uf2disk.py +12 -12
  35. mpflash/mpflash/flash/uf2/windows.py +43 -43
  36. mpflash/mpflash/flash/worklist.py +170 -170
  37. mpflash/mpflash/list.py +106 -106
  38. mpflash/mpflash/logger.py +41 -41
  39. mpflash/mpflash/mpboard_id/__init__.py +93 -93
  40. mpflash/mpflash/mpboard_id/add_boards.py +251 -251
  41. mpflash/mpflash/mpboard_id/board.py +37 -37
  42. mpflash/mpflash/mpboard_id/board_id.py +86 -86
  43. mpflash/mpflash/mpboard_id/store.py +43 -43
  44. mpflash/mpflash/mpremoteboard/__init__.py +266 -266
  45. mpflash/mpflash/mpremoteboard/mpy_fw_info.py +141 -141
  46. mpflash/mpflash/mpremoteboard/runner.py +140 -140
  47. mpflash/mpflash/vendor/click_aliases.py +91 -91
  48. mpflash/mpflash/vendor/dfu.py +165 -165
  49. mpflash/mpflash/vendor/pydfu.py +605 -605
  50. mpflash/mpflash/vendor/readme.md +2 -2
  51. mpflash/mpflash/versions.py +135 -135
  52. mpflash/poetry.lock +1599 -1599
  53. mpflash/pyproject.toml +65 -65
  54. mpflash/stm32_udev_rules.md +62 -62
  55. stubber/__init__.py +3 -3
  56. stubber/board/board_info.csv +193 -193
  57. stubber/board/boot.py +34 -34
  58. stubber/board/createstubs.py +1004 -986
  59. stubber/board/createstubs_db.py +826 -825
  60. stubber/board/createstubs_db_min.py +332 -331
  61. stubber/board/createstubs_db_mpy.mpy +0 -0
  62. stubber/board/createstubs_lvgl.py +741 -741
  63. stubber/board/createstubs_lvgl_min.py +741 -741
  64. stubber/board/createstubs_mem.py +767 -766
  65. stubber/board/createstubs_mem_min.py +307 -306
  66. stubber/board/createstubs_mem_mpy.mpy +0 -0
  67. stubber/board/createstubs_min.py +295 -294
  68. stubber/board/createstubs_mpy.mpy +0 -0
  69. stubber/board/fw_info.py +141 -141
  70. stubber/board/info.py +183 -183
  71. stubber/board/main.py +19 -19
  72. stubber/board/modulelist.txt +247 -247
  73. stubber/board/pyrightconfig.json +34 -34
  74. stubber/bulk/mcu_stubber.py +437 -437
  75. stubber/codemod/_partials/__init__.py +48 -48
  76. stubber/codemod/_partials/db_main.py +147 -147
  77. stubber/codemod/_partials/lvgl_main.py +77 -77
  78. stubber/codemod/_partials/modules_reader.py +80 -80
  79. stubber/codemod/add_comment.py +53 -53
  80. stubber/codemod/add_method.py +65 -65
  81. stubber/codemod/board.py +317 -317
  82. stubber/codemod/enrich.py +151 -145
  83. stubber/codemod/merge_docstub.py +284 -284
  84. stubber/codemod/modify_list.py +54 -54
  85. stubber/codemod/utils.py +56 -56
  86. stubber/commands/build_cmd.py +94 -94
  87. stubber/commands/cli.py +49 -49
  88. stubber/commands/clone_cmd.py +78 -78
  89. stubber/commands/config_cmd.py +29 -29
  90. stubber/commands/enrich_folder_cmd.py +71 -71
  91. stubber/commands/get_core_cmd.py +71 -71
  92. stubber/commands/get_docstubs_cmd.py +92 -92
  93. stubber/commands/get_frozen_cmd.py +117 -117
  94. stubber/commands/get_mcu_cmd.py +102 -102
  95. stubber/commands/merge_cmd.py +66 -66
  96. stubber/commands/publish_cmd.py +118 -118
  97. stubber/commands/stub_cmd.py +31 -31
  98. stubber/commands/switch_cmd.py +62 -62
  99. stubber/commands/variants_cmd.py +48 -48
  100. stubber/cst_transformer.py +178 -178
  101. stubber/data/board_info.csv +193 -193
  102. stubber/data/board_info.json +1729 -1729
  103. stubber/data/micropython_tags.csv +15 -15
  104. stubber/data/requirements-core-micropython.txt +38 -38
  105. stubber/data/requirements-core-pycopy.txt +39 -39
  106. stubber/downloader.py +37 -37
  107. stubber/freeze/common.py +72 -72
  108. stubber/freeze/freeze_folder.py +69 -69
  109. stubber/freeze/freeze_manifest_2.py +126 -126
  110. stubber/freeze/get_frozen.py +131 -131
  111. stubber/get_cpython.py +112 -112
  112. stubber/get_lobo.py +59 -59
  113. stubber/minify.py +423 -423
  114. stubber/publish/bump.py +86 -86
  115. stubber/publish/candidates.py +275 -275
  116. stubber/publish/database.py +18 -18
  117. stubber/publish/defaults.py +40 -40
  118. stubber/publish/enums.py +24 -24
  119. stubber/publish/helpers.py +29 -29
  120. stubber/publish/merge_docstubs.py +136 -132
  121. stubber/publish/missing_class_methods.py +51 -51
  122. stubber/publish/package.py +150 -150
  123. stubber/publish/pathnames.py +51 -51
  124. stubber/publish/publish.py +120 -120
  125. stubber/publish/pypi.py +42 -42
  126. stubber/publish/stubpackage.py +1055 -1051
  127. stubber/rst/__init__.py +9 -9
  128. stubber/rst/classsort.py +78 -78
  129. stubber/rst/lookup.py +533 -531
  130. stubber/rst/output_dict.py +401 -401
  131. stubber/rst/reader.py +814 -814
  132. stubber/rst/report_return.py +77 -77
  133. stubber/rst/rst_utils.py +541 -541
  134. stubber/stubber.py +38 -38
  135. stubber/stubs_from_docs.py +90 -90
  136. stubber/tools/manifestfile.py +654 -654
  137. stubber/tools/readme.md +6 -6
  138. stubber/update_fallback.py +117 -117
  139. stubber/update_module_list.py +123 -123
  140. stubber/utils/__init__.py +6 -6
  141. stubber/utils/config.py +137 -137
  142. stubber/utils/makeversionhdr.py +54 -54
  143. stubber/utils/manifest.py +90 -90
  144. stubber/utils/post.py +80 -80
  145. stubber/utils/repos.py +156 -156
  146. stubber/utils/stubmaker.py +139 -139
  147. stubber/utils/typed_config_toml.py +80 -80
  148. stubber/variants.py +106 -106
  149. micropython_stubber-1.23.1.post1.dist-info/RECORD +0 -159
  150. mpflash/basicgit.py +0 -288
  151. {micropython_stubber-1.23.1.post1.dist-info → micropython_stubber-1.23.2.dist-info}/WHEEL +0 -0
  152. {micropython_stubber-1.23.1.post1.dist-info → micropython_stubber-1.23.2.dist-info}/entry_points.txt +0 -0
@@ -1,40 +1,40 @@
1
- """Build and packaging defaults for stubber"""
2
-
3
- from typing import Dict, List
4
-
5
- from mpflash.versions import V_PREVIEW, clean_version
6
- from stubber.utils.config import CONFIG
7
-
8
- # The default board for the ports modules documented with base name only
9
- # as the MicroPython BOARD naming convention has changed over time there are different options to try
10
- # (newer to older)
11
-
12
- DEFAULT_BOARDS: Dict[str, List[str]] = {
13
- "stm32": ["PYBV11", ""],
14
- "esp32": ["ESP32_GENERIC", "GENERIC", ""], # "GENERIC_SPIRAM",
15
- "esp8266": ["ESP8266_GENERIC", "GENERIC", ""],
16
- "rp2": ["RPI_PICO", "PICO", ""],
17
- "samd": ["SEEED_WIO_TERMINAL", ""],
18
- }
19
-
20
- GENERIC_L = "generic"
21
- "generic lowercase"
22
- GENERIC_U = "GENERIC"
23
- "GENERIC uppercase"
24
- GENERIC = {GENERIC_L, GENERIC_U}
25
- "GENERIC eithercase"
26
-
27
-
28
- def default_board(port: str, version=V_PREVIEW) -> str: # sourcery skip: assign-if-exp
29
- """Return the default board for the given version and port"""
30
- ver_flat = clean_version(version, flat=True)
31
- if port in DEFAULT_BOARDS:
32
- for board in DEFAULT_BOARDS[port]:
33
- base = f"micropython-{ver_flat}-{port}-{board}" if board else f"micropython-{ver_flat}-{port}"
34
- # check if we have a (merged)stub for this version and port
35
- if (CONFIG.stub_path / f"{base}-merged").exists() or (CONFIG.stub_path / base).exists():
36
- return board
37
- # fallback to first listed board
38
- return DEFAULT_BOARDS[port][0]
39
- # fallback to generic
40
- return GENERIC_U
1
+ """Build and packaging defaults for stubber"""
2
+
3
+ from typing import Dict, List
4
+
5
+ from mpflash.versions import V_PREVIEW, clean_version
6
+ from stubber.utils.config import CONFIG
7
+
8
+ # The default board for the ports modules documented with base name only
9
+ # as the MicroPython BOARD naming convention has changed over time there are different options to try
10
+ # (newer to older)
11
+
12
+ DEFAULT_BOARDS: Dict[str, List[str]] = {
13
+ "stm32": ["PYBV11", ""],
14
+ "esp32": ["ESP32_GENERIC", "GENERIC", ""], # "GENERIC_SPIRAM",
15
+ "esp8266": ["ESP8266_GENERIC", "GENERIC", ""],
16
+ "rp2": ["RPI_PICO", "PICO", ""],
17
+ "samd": ["SEEED_WIO_TERMINAL", ""],
18
+ }
19
+
20
+ GENERIC_L = "generic"
21
+ "generic lowercase"
22
+ GENERIC_U = "GENERIC"
23
+ "GENERIC uppercase"
24
+ GENERIC = {GENERIC_L, GENERIC_U}
25
+ "GENERIC eithercase"
26
+
27
+
28
+ def default_board(port: str, version=V_PREVIEW) -> str: # sourcery skip: assign-if-exp
29
+ """Return the default board for the given version and port"""
30
+ ver_flat = clean_version(version, flat=True)
31
+ if port in DEFAULT_BOARDS:
32
+ for board in DEFAULT_BOARDS[port]:
33
+ base = f"micropython-{ver_flat}-{port}-{board}" if board else f"micropython-{ver_flat}-{port}"
34
+ # check if we have a (merged)stub for this version and port
35
+ if (CONFIG.stub_path / f"{base}-merged").exists() or (CONFIG.stub_path / base).exists():
36
+ return board
37
+ # fallback to first listed board
38
+ return DEFAULT_BOARDS[port][0]
39
+ # fallback to generic
40
+ return GENERIC_U
stubber/publish/enums.py CHANGED
@@ -1,24 +1,24 @@
1
- """Enumerations for the stubber package."""
2
- from enum import Enum
3
-
4
-
5
- class StubSource(str, Enum):
6
- FIRMWARE = "MCU stubs"
7
- "stubs built by combining the firmware, frozen and core stubs"
8
- FROZEN = "Frozen stubs"
9
- "stubs of python modules that are frozen as part of the firmware image"
10
- CORE = "Core stubs"
11
- "stubs that allow (some) MicroPython code to be run by CPython"
12
- DOC = "Doc stubs"
13
- "stubs built by parsing the micropython RST documentation files"
14
- MERGED = "Merged stubs"
15
- "stubs built by merging the information from doc-stubs and MCU stubs"
16
-
17
- def __str__(self):
18
- # Always force string values
19
- return self.value
20
-
21
- def __repr__(self):
22
- # Always force string values
23
- return self.value
24
-
1
+ """Enumerations for the stubber package."""
2
+ from enum import Enum
3
+
4
+
5
+ class StubSource(str, Enum):
6
+ FIRMWARE = "MCU stubs"
7
+ "stubs built by combining the firmware, frozen and core stubs"
8
+ FROZEN = "Frozen stubs"
9
+ "stubs of python modules that are frozen as part of the firmware image"
10
+ CORE = "Core stubs"
11
+ "stubs that allow (some) MicroPython code to be run by CPython"
12
+ DOC = "Doc stubs"
13
+ "stubs built by parsing the micropython RST documentation files"
14
+ MERGED = "Merged stubs"
15
+ "stubs built by merging the information from doc-stubs and MCU stubs"
16
+
17
+ def __str__(self):
18
+ # Always force string values
19
+ return self.value
20
+
21
+ def __repr__(self):
22
+ # Always force string values
23
+ return self.value
24
+
@@ -1,29 +1,29 @@
1
- """
2
- This module provides a function to retrieve the docstring of a Python module.
3
- """
4
-
5
- from pathlib import Path
6
- from typing import Any, Union
7
-
8
- import libcst as cst
9
-
10
-
11
- def get_module_docstring(fname: Path) -> Union[str, Any]:
12
- """
13
- Retrieve the docstring of a Python module.
14
-
15
- Args:
16
- fname (Path): The path to the Python module file.
17
-
18
- Returns:
19
- Union[str, Any]: The docstring of the Python module, or None if no docstring is found.
20
- """
21
- try:
22
- with open(fname, "r") as file:
23
- content = file.read()
24
- mod = cst.parse_module(content)
25
- return mod.get_docstring()
26
- except Exception as e:
27
- print(e)
28
- return None
29
-
1
+ """
2
+ This module provides a function to retrieve the docstring of a Python module.
3
+ """
4
+
5
+ from pathlib import Path
6
+ from typing import Any, Union
7
+
8
+ import libcst as cst
9
+
10
+
11
+ def get_module_docstring(fname: Path) -> Union[str, Any]:
12
+ """
13
+ Retrieve the docstring of a Python module.
14
+
15
+ Args:
16
+ fname (Path): The path to the Python module file.
17
+
18
+ Returns:
19
+ Union[str, Any]: The docstring of the Python module, or None if no docstring is found.
20
+ """
21
+ try:
22
+ with open(fname, "r") as file:
23
+ content = file.read()
24
+ mod = cst.parse_module(content)
25
+ return mod.get_docstring()
26
+ except Exception as e:
27
+ print(e)
28
+ return None
29
+
@@ -1,132 +1,136 @@
1
- """
2
- Merge MCU stubs and docstubs into a single folder
3
- """
4
-
5
- import shutil
6
- from pathlib import Path
7
- from typing import List, Optional, Union
8
-
9
- from mpflash.logger import log
10
-
11
- from stubber.codemod.enrich import enrich_folder
12
- from stubber.publish.candidates import board_candidates, filter_list
13
- from stubber.publish.defaults import GENERIC, GENERIC_L, default_board
14
- from stubber.publish.missing_class_methods import add_machine_pin_call
15
- from stubber.publish.pathnames import get_base, get_board_path, get_merged_path
16
- from stubber.utils.config import CONFIG
17
-
18
-
19
- def merge_all_docstubs(
20
- versions: Optional[Union[List[str], str]] = None,
21
- family: str = "micropython",
22
- ports: Optional[Union[List[str], str]] = None,
23
- boards: Optional[Union[List[str], str]] = None,
24
- *,
25
- mpy_path: Path = CONFIG.mpy_path,
26
- ):
27
- """merge docstubs and MCU stubs to merged stubs"""
28
- if versions is None:
29
- versions = [CONFIG.stable_version]
30
- if ports is None:
31
- ports = ["all"]
32
- if boards is None:
33
- boards = [GENERIC_L]
34
- if isinstance(versions, str):
35
- versions = [versions]
36
- if isinstance(ports, str):
37
- ports = [ports]
38
- if isinstance(boards, str):
39
- boards = [boards]
40
-
41
- candidates = list(board_candidates(versions=versions, family=family))
42
- candidates = filter_list(candidates, ports, boards)
43
- if not candidates:
44
- log.error("No candidates found")
45
- return
46
-
47
- log.info(f"checking {len(candidates)} possible board candidates")
48
- merged = 0
49
- for candidate in candidates:
50
- # use the default board for the port
51
- if candidate["board"] in GENERIC:
52
- candidate["board"] = default_board(
53
- port=candidate["port"], version=candidate["version"]
54
- )
55
- # check if we have MCU stubs of this version and port
56
- doc_path = CONFIG.stub_path / f"{get_base(candidate)}-docstubs"
57
- # src and dest paths
58
- board_path = get_board_path(candidate)
59
- merged_path = get_merged_path(candidate)
60
-
61
- # only continue if both folders exist
62
- if not doc_path.exists():
63
- log.warning(f"No docstubs found for {candidate['version']}")
64
- continue
65
- if not board_path.exists():
66
- log.info(f"skipping {merged_path.name}, no MCU stubs found in {board_path}")
67
- continue
68
- log.info(f"Merge {candidate['version']} docstubs with boardstubs to {merged_path.name}")
69
- result = copy_and_merge_docstubs(board_path, merged_path, doc_path)
70
- # Add methods from docstubs to the MCU stubs that do not exist in the MCU stubs
71
- # Add the __call__ method to the machine.Pin and pyb.Pin class
72
- add_machine_pin_call(merged_path, candidate["version"])
73
- if result:
74
- merged += 1
75
- log.info(f"merged {merged} of {len(candidates)} candidates")
76
- return merged
77
-
78
-
79
- def copy_and_merge_docstubs(fw_path: Path, dest_path: Path, docstub_path: Path):
80
- """
81
- Parameters:
82
- fw_path: Path to MCU stubs (absolute path)
83
- dest_path: Path to destination (absolute path)
84
- mpy_version: micropython version ('1.18')
85
-
86
- Copy files from the firmware stub folders to the merged
87
- - 1 - Copy all MCU stubs to the package folder
88
- - 1.B - clean up a little bit
89
- - 2 - Enrich the MCU stubs with the document stubs
90
-
91
- """
92
- if dest_path.exists():
93
- # delete all files and folders from the destination
94
- shutil.rmtree(dest_path, ignore_errors=True)
95
- dest_path.mkdir(parents=True, exist_ok=True)
96
-
97
- # 1 - Copy the stubs to the package, directly in the package folder (no folders)
98
- try:
99
- log.debug(f"Copying MCU stubs from {fw_path}")
100
- shutil.copytree(fw_path, dest_path, symlinks=True, dirs_exist_ok=True)
101
- except OSError as e:
102
- log.error(f"Error copying stubs from : { fw_path}, {e}")
103
- raise (e)
104
- # rename the module.json file to firmware.json
105
- if (dest_path / "modules.json").exists():
106
- (dest_path / "modules.json").rename(dest_path / "firmware_stubs.json")
107
-
108
- # avoid duplicate modules : folder - file combinations
109
- # prefer folder from frozen stubs, over file from MCU stubs
110
- # No frozen here - OLD code ?
111
- for f in dest_path.glob("*"):
112
- if f.is_dir():
113
- for suffix in [".py", ".pyi"]:
114
- if (dest_path / f.name).with_suffix(suffix).exists():
115
- (dest_path / f.name).with_suffix(suffix).unlink()
116
-
117
- # delete builtins.pyi in the package folder
118
- for name in [
119
- "builtins", # creates conflicts, better removed
120
- "pycopy_imphook", # is not intended to be used directly, and has an unresolved subclass
121
- ]:
122
- for suffix in [".py", ".pyi"]:
123
- if (dest_path / name).with_suffix(suffix).exists(): # type: ignore
124
- (dest_path / name).with_suffix(suffix).unlink() # type: ignore
125
-
126
- # 2 - Enrich the MCU stubs with the document stubs
127
- result = enrich_folder(dest_path, docstub_path=docstub_path, write_back=True)
128
-
129
- # copy the docstubs manifest.json file to the package folder
130
- if (docstub_path / "modules.json").exists():
131
- shutil.copy(docstub_path / "modules.json", dest_path / "doc_stubs.json")
132
- return result
1
+ """
2
+ Merge MCU stubs and docstubs into a single folder
3
+ """
4
+
5
+ import shutil
6
+ from pathlib import Path
7
+ from typing import List, Optional, Union
8
+
9
+ from mpflash.logger import log
10
+
11
+ from stubber.codemod.enrich import enrich_folder
12
+ from stubber.publish.candidates import board_candidates, filter_list
13
+ from stubber.publish.defaults import GENERIC, GENERIC_L, default_board
14
+ from stubber.publish.missing_class_methods import add_machine_pin_call
15
+ from stubber.publish.pathnames import get_base, get_board_path, get_merged_path
16
+ from stubber.utils.config import CONFIG
17
+
18
+
19
+ def merge_all_docstubs(
20
+ versions: Optional[Union[List[str], str]] = None,
21
+ family: str = "micropython",
22
+ ports: Optional[Union[List[str], str]] = None,
23
+ boards: Optional[Union[List[str], str]] = None,
24
+ *,
25
+ mpy_path: Path = CONFIG.mpy_path,
26
+ ):
27
+ """merge docstubs and MCU stubs to merged stubs"""
28
+ if versions is None:
29
+ versions = [CONFIG.stable_version]
30
+ if ports is None:
31
+ ports = ["all"]
32
+ if boards is None:
33
+ boards = [GENERIC_L]
34
+ if isinstance(versions, str):
35
+ versions = [versions]
36
+ if isinstance(ports, str):
37
+ ports = [ports]
38
+ if isinstance(boards, str):
39
+ boards = [boards]
40
+
41
+ candidates = list(board_candidates(versions=versions, family=family))
42
+ candidates = filter_list(candidates, ports, boards)
43
+ if not candidates:
44
+ log.error("No candidates found")
45
+ return
46
+
47
+ log.info(f"checking {len(candidates)} possible board candidates")
48
+ merged = 0
49
+ for candidate in candidates:
50
+ # use the default board for the port
51
+ if candidate["board"] in GENERIC:
52
+ candidate["board"] = default_board(
53
+ port=candidate["port"], version=candidate["version"]
54
+ )
55
+ # check if we have MCU stubs of this version and port
56
+ doc_path = CONFIG.stub_path / f"{get_base(candidate)}-docstubs"
57
+ # src and dest paths
58
+ board_path = get_board_path(candidate)
59
+ merged_path = get_merged_path(candidate)
60
+
61
+ # only continue if both folders exist
62
+ if not doc_path.exists():
63
+ log.warning(f"No docstubs found for {candidate['version']}")
64
+ continue
65
+ if not board_path.exists():
66
+ log.info(f"skipping {merged_path.name}, no MCU stubs found in {board_path}")
67
+ continue
68
+ log.info(f"Merge {candidate['version']} docstubs with boardstubs to {merged_path.name}")
69
+ try:
70
+ result = copy_and_merge_docstubs(board_path, merged_path, doc_path)
71
+ # Add methods from docstubs to the MCU stubs that do not exist in the MCU stubs
72
+ # Add the __call__ method to the machine.Pin and pyb.Pin class
73
+ add_machine_pin_call(merged_path, candidate["version"])
74
+ except Exception as e:
75
+ log.error(f"Error parsing {candidate['version']} docstubs: {e}")
76
+ continue
77
+ if result:
78
+ merged += 1
79
+ log.info(f"merged {merged} of {len(candidates)} candidates")
80
+ return merged
81
+
82
+
83
+ def copy_and_merge_docstubs(fw_path: Path, dest_path: Path, docstub_path: Path):
84
+ """
85
+ Parameters:
86
+ fw_path: Path to MCU stubs (absolute path)
87
+ dest_path: Path to destination (absolute path)
88
+ mpy_version: micropython version ('1.18')
89
+
90
+ Copy files from the firmware stub folders to the merged
91
+ - 1 - Copy all MCU stubs to the package folder
92
+ - 1.B - clean up a little bit
93
+ - 2 - Enrich the MCU stubs with the document stubs
94
+
95
+ """
96
+ if dest_path.exists():
97
+ # delete all files and folders from the destination
98
+ shutil.rmtree(dest_path, ignore_errors=True)
99
+ dest_path.mkdir(parents=True, exist_ok=True)
100
+
101
+ # 1 - Copy the stubs to the package, directly in the package folder (no folders)
102
+ try:
103
+ log.debug(f"Copying MCU stubs from {fw_path}")
104
+ shutil.copytree(fw_path, dest_path, symlinks=True, dirs_exist_ok=True)
105
+ except OSError as e:
106
+ log.error(f"Error copying stubs from : { fw_path}, {e}")
107
+ raise (e)
108
+ # rename the module.json file to firmware.json
109
+ if (dest_path / "modules.json").exists():
110
+ (dest_path / "modules.json").rename(dest_path / "firmware_stubs.json")
111
+
112
+ # avoid duplicate modules : folder - file combinations
113
+ # prefer folder from frozen stubs, over file from MCU stubs
114
+ # No frozen here - OLD code ?
115
+ for f in dest_path.glob("*"):
116
+ if f.is_dir():
117
+ for suffix in [".py", ".pyi"]:
118
+ if (dest_path / f.name).with_suffix(suffix).exists():
119
+ (dest_path / f.name).with_suffix(suffix).unlink()
120
+
121
+ # delete builtins.pyi in the package folder
122
+ for name in [
123
+ "builtins", # creates conflicts, better removed
124
+ "pycopy_imphook", # is not intended to be used directly, and has an unresolved subclass
125
+ ]:
126
+ for suffix in [".py", ".pyi"]:
127
+ if (dest_path / name).with_suffix(suffix).exists(): # type: ignore
128
+ (dest_path / name).with_suffix(suffix).unlink() # type: ignore
129
+
130
+ # 2 - Enrich the MCU stubs with the document stubs
131
+ result = enrich_folder(dest_path, docstub_path=docstub_path, write_back=True)
132
+
133
+ # copy the docstubs manifest.json file to the package folder
134
+ if (docstub_path / "modules.json").exists():
135
+ shutil.copy(docstub_path / "modules.json", dest_path / "doc_stubs.json")
136
+ return result
@@ -1,51 +1,51 @@
1
- """
2
- Add missing methods to classes in the stubs that are documented in the docstubs
3
-
4
- """
5
-
6
- from pathlib import Path
7
-
8
- import libcst as cst
9
- from mpflash.logger import log
10
-
11
- from mpflash.versions import clean_version
12
- from stubber.codemod.add_method import CallAdder, CallFinder
13
- from stubber.utils.config import CONFIG
14
- from stubber.utils.post import run_black
15
-
16
-
17
- def add_machine_pin_call(merged_path: Path, version: str):
18
- """
19
- Add the __call__ method to the machine.Pin and pyb.Pin class
20
- in all pyb and machine/umachine stubs
21
- """
22
- # TODO: this should be done in the merge_docstubs.py to avoid needing to run black twice
23
- # and to avoid having to parse the file twice
24
-
25
- # first find the __call__ method in the default stubs
26
- mod_path = (
27
- CONFIG.stub_path / f"micropython-{clean_version(version, flat=True)}-docstubs/machine.pyi"
28
- )
29
- if not mod_path.exists():
30
- log.error(f"no docstubs found for {version}")
31
- return False
32
- log.trace(f"Parsing {mod_path} for __call__ method")
33
- source = mod_path.read_text(encoding="utf-8")
34
- module = cst.parse_module(source)
35
-
36
- call_finder = CallFinder()
37
- module.visit(call_finder)
38
-
39
- if call_finder.call_meth is None:
40
- log.error("no __call__ method found")
41
- return False
42
-
43
- # then use the CallAdder to add the __call__ method to all machine and pyb stubs
44
- mod_paths = [f for f in merged_path.rglob("*.*") if f.stem in {"machine", "umachine", "pyb"}]
45
- for mod_path in mod_paths:
46
- source = mod_path.read_text(encoding="utf-8")
47
- machine_module = cst.parse_module(source)
48
- new_module = machine_module.visit(CallAdder(call_finder.call_meth))
49
- mod_path.write_text(new_module.code, encoding="utf-8")
50
- run_black(mod_path)
51
- return True
1
+ """
2
+ Add missing methods to classes in the stubs that are documented in the docstubs
3
+
4
+ """
5
+
6
+ from pathlib import Path
7
+
8
+ import libcst as cst
9
+ from mpflash.logger import log
10
+
11
+ from mpflash.versions import clean_version
12
+ from stubber.codemod.add_method import CallAdder, CallFinder
13
+ from stubber.utils.config import CONFIG
14
+ from stubber.utils.post import run_black
15
+
16
+
17
+ def add_machine_pin_call(merged_path: Path, version: str):
18
+ """
19
+ Add the __call__ method to the machine.Pin and pyb.Pin class
20
+ in all pyb and machine/umachine stubs
21
+ """
22
+ # TODO: this should be done in the merge_docstubs.py to avoid needing to run black twice
23
+ # and to avoid having to parse the file twice
24
+
25
+ # first find the __call__ method in the default stubs
26
+ mod_path = (
27
+ CONFIG.stub_path / f"micropython-{clean_version(version, flat=True)}-docstubs/machine.pyi"
28
+ )
29
+ if not mod_path.exists():
30
+ log.error(f"no docstubs found for {version}")
31
+ return False
32
+ log.trace(f"Parsing {mod_path} for __call__ method")
33
+ source = mod_path.read_text(encoding="utf-8")
34
+ module = cst.parse_module(source)
35
+
36
+ call_finder = CallFinder()
37
+ module.visit(call_finder)
38
+
39
+ if call_finder.call_meth is None:
40
+ log.error("no __call__ method found")
41
+ return False
42
+
43
+ # then use the CallAdder to add the __call__ method to all machine and pyb stubs
44
+ mod_paths = [f for f in merged_path.rglob("*.*") if f.stem in {"machine", "umachine", "pyb"}]
45
+ for mod_path in mod_paths:
46
+ source = mod_path.read_text(encoding="utf-8")
47
+ machine_module = cst.parse_module(source)
48
+ new_module = machine_module.visit(CallAdder(call_finder.call_meth))
49
+ mod_path.write_text(new_module.code, encoding="utf-8")
50
+ run_black(mod_path)
51
+ return True