micropython-stubber 1.16.2__py3-none-any.whl → 1.17.0__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.
- {micropython_stubber-1.16.2.dist-info → micropython_stubber-1.17.0.dist-info}/METADATA +2 -1
- {micropython_stubber-1.16.2.dist-info → micropython_stubber-1.17.0.dist-info}/RECORD +54 -54
- stubber/__init__.py +1 -1
- stubber/basicgit.py +27 -33
- stubber/board/board_info.csv +137 -103
- stubber/board/createstubs.py +222 -189
- stubber/board/createstubs_db.py +284 -214
- stubber/board/createstubs_db_min.py +286 -265
- stubber/board/createstubs_db_mpy.mpy +0 -0
- stubber/board/createstubs_lvgl.py +171 -113
- stubber/board/createstubs_lvgl_min.py +738 -275
- stubber/board/createstubs_lvgl_mpy.mpy +0 -0
- stubber/board/createstubs_mem.py +237 -174
- stubber/board/createstubs_mem_min.py +263 -247
- stubber/board/createstubs_mem_mpy.mpy +0 -0
- stubber/board/createstubs_min.py +242 -227
- stubber/board/createstubs_mpy.mpy +0 -0
- stubber/board/fw_info.py +135 -0
- stubber/board/modulelist.txt +1 -2
- stubber/codemod/_partials/__init__.py +1 -1
- stubber/codemod/_partials/db_main.py +90 -72
- stubber/codemod/_partials/modules_reader.py +29 -17
- stubber/codemod/board.py +2 -4
- stubber/codemod/enrich.py +1 -1
- stubber/commands/build_cmd.py +6 -4
- stubber/commands/get_docstubs_cmd.py +6 -11
- stubber/commands/get_frozen_cmd.py +6 -11
- stubber/commands/switch_cmd.py +6 -4
- stubber/data/board_info.csv +134 -101
- stubber/data/board_info.json +1357 -901
- stubber/freeze/freeze_manifest_2.py +2 -1
- stubber/freeze/get_frozen.py +28 -13
- stubber/minify.py +56 -43
- stubber/publish/candidates.py +15 -23
- stubber/publish/defaults.py +2 -2
- stubber/publish/merge_docstubs.py +5 -7
- stubber/publish/missing_class_methods.py +2 -2
- stubber/publish/pathnames.py +2 -2
- stubber/publish/publish.py +2 -1
- stubber/publish/stubpackage.py +20 -40
- stubber/rst/lookup.py +9 -7
- stubber/rst/reader.py +2 -1
- stubber/stubber.py +5 -6
- stubber/update_fallback.py +3 -1
- stubber/update_module_list.py +1 -1
- stubber/utils/__init__.py +1 -1
- stubber/utils/config.py +7 -9
- stubber/utils/post.py +1 -1
- stubber/utils/repos.py +10 -7
- stubber/utils/versions.py +48 -7
- stubber/variants.py +3 -3
- stubber/board/logging.py +0 -99
- {micropython_stubber-1.16.2.dist-info → micropython_stubber-1.17.0.dist-info}/LICENSE +0 -0
- {micropython_stubber-1.16.2.dist-info → micropython_stubber-1.17.0.dist-info}/WHEEL +0 -0
- {micropython_stubber-1.16.2.dist-info → micropython_stubber-1.17.0.dist-info}/entry_points.txt +0 -0
@@ -57,7 +57,8 @@ def freeze_one_manifest_2(manifest: Path, frozen_stub_path: Path, mpy_path: Path
|
|
57
57
|
# so we need to get the port and board from the path
|
58
58
|
log.info(f"input_manifest: {manifest}")
|
59
59
|
port, board = get_portboard(manifest)
|
60
|
-
|
60
|
+
|
61
|
+
log.info("port-board: {}".format((port + "-" +board).rstrip("-")))
|
61
62
|
|
62
63
|
path_vars = make_path_vars(port=port, board=board, mpy_path=mpy_path, mpy_lib_path=mpy_lib_path)
|
63
64
|
upy_manifest = ManifestFile(MODE_FREEZE, path_vars)
|
stubber/freeze/get_frozen.py
CHANGED
@@ -24,14 +24,15 @@ from typing import List, Optional
|
|
24
24
|
|
25
25
|
from loguru import logger as log
|
26
26
|
from packaging.version import Version
|
27
|
+
|
28
|
+
import stubber.basicgit as git
|
27
29
|
from stubber import utils
|
30
|
+
from stubber.codemod.add_comment import AddComment
|
28
31
|
from stubber.freeze.freeze_folder import freeze_folders # Micropython < v1.12
|
29
32
|
from stubber.freeze.freeze_manifest_2 import freeze_one_manifest_2
|
30
33
|
from stubber.utils.config import CONFIG
|
31
|
-
from stubber.
|
32
|
-
|
34
|
+
from stubber.utils.versions import SET_PREVIEW, V_PREVIEW
|
33
35
|
|
34
|
-
# globals
|
35
36
|
FAMILY = "micropython"
|
36
37
|
|
37
38
|
|
@@ -54,13 +55,18 @@ def add_comment_to_path(path: Path, comment: str) -> None:
|
|
54
55
|
Add a comment to the top of each file in the path
|
55
56
|
using a codemod
|
56
57
|
"""
|
57
|
-
#TODO: #305 add comment line to each file with the micropython version it was generated from
|
58
|
+
# TODO: #305 add comment line to each file with the micropython version it was generated from
|
58
59
|
# frozen_stub_path
|
59
60
|
# python -m libcst.tool codemod --include-stubs --no-format add_comment.AddComment .\repos\micropython-stubs\stubs\micropython-v1_19_1-frozen\ --comment "# Micropython 1.19.1 frozen stubs"
|
60
61
|
pass
|
61
62
|
|
62
63
|
|
63
|
-
def freeze_any(
|
64
|
+
def freeze_any(
|
65
|
+
stub_folder: Optional[Path] = None,
|
66
|
+
version: str = V_PREVIEW,
|
67
|
+
mpy_path: Optional[Path] = None,
|
68
|
+
mpy_lib_path: Optional[Path] = None,
|
69
|
+
) -> Path:
|
64
70
|
"""
|
65
71
|
Get and parse the to-be-frozen .py modules for micropython to extract the static type information
|
66
72
|
- requires that the MicroPython and Micropython-lib repos are checked out and available on a local path
|
@@ -73,24 +79,24 @@ def freeze_any(stub_folder: Path, version: str, mpy_path: Optional[Path] = None,
|
|
73
79
|
current_dir = os.getcwd()
|
74
80
|
mpy_path = Path(mpy_path).absolute() if mpy_path else CONFIG.mpy_path.absolute()
|
75
81
|
mpy_lib_path = Path(mpy_lib_path).absolute() if mpy_lib_path else CONFIG.mpy_path.absolute()
|
76
|
-
if not stub_folder:
|
77
|
-
frozen_stub_path = Path("{}/{}_{}_frozen".format(CONFIG.stub_path, FAMILY, utils.clean_version(version, flat=True))).absolute()
|
78
|
-
else:
|
79
|
-
frozen_stub_path: Path = Path(stub_folder).absolute()
|
80
82
|
|
81
83
|
# if old version of micropython, use the old freeze method
|
82
|
-
if version not in
|
84
|
+
if version not in SET_PREVIEW and Version(version) <= Version("1.11"):
|
85
|
+
frozen_stub_path = get_fsp(version, stub_folder)
|
83
86
|
log.debug("MicroPython v1.11, older or other")
|
84
87
|
# others
|
85
88
|
modules = freeze_folders(frozen_stub_path.as_posix(), mpy_path.as_posix(), mpy_lib_path.as_posix(), version)
|
86
89
|
count = len(modules)
|
87
90
|
else:
|
91
|
+
# get the current checked out version
|
92
|
+
version = utils.checkedout_version(CONFIG.mpy_path)
|
93
|
+
|
94
|
+
frozen_stub_path = get_fsp(version, stub_folder)
|
88
95
|
# get the manifests of the different ports and boards
|
89
96
|
all_manifests = get_manifests(mpy_path)
|
90
97
|
|
91
98
|
# process all_manifests under the ports folder and update the frozen files in the stubs folder
|
92
|
-
# we are
|
93
|
-
frozen_stub_path = frozen_stub_path.absolute()
|
99
|
+
# we are going to jump around, avoid relative paths
|
94
100
|
mpy_path = mpy_path.absolute()
|
95
101
|
mpy_lib_path = mpy_lib_path.absolute()
|
96
102
|
|
@@ -111,4 +117,13 @@ def freeze_any(stub_folder: Path, version: str, mpy_path: Optional[Path] = None,
|
|
111
117
|
|
112
118
|
# restore cwd
|
113
119
|
os.chdir(current_dir)
|
114
|
-
return
|
120
|
+
return frozen_stub_path
|
121
|
+
|
122
|
+
|
123
|
+
def get_fsp(version: str, stub_folder: Optional[Path] = None) -> Path:
|
124
|
+
if not stub_folder:
|
125
|
+
frozen_stub_path = CONFIG.stub_path / f"{FAMILY}-{utils.clean_version(version, flat=True)}-frozen"
|
126
|
+
frozen_stub_path = frozen_stub_path.absolute()
|
127
|
+
else:
|
128
|
+
frozen_stub_path: Path = Path(stub_folder).absolute()
|
129
|
+
return frozen_stub_path
|
stubber/minify.py
CHANGED
@@ -13,6 +13,8 @@ from typing import List, Tuple, Union
|
|
13
13
|
import python_minifier
|
14
14
|
from loguru import logger as log
|
15
15
|
|
16
|
+
from stubber.utils.versions import SET_PREVIEW, V_PREVIEW
|
17
|
+
|
16
18
|
# Type Aliases for minify
|
17
19
|
StubSource = Union[Path, str, StringIO, TextIOWrapper]
|
18
20
|
XCompileDest = Union[Path, BytesIO]
|
@@ -192,19 +194,62 @@ def minify_script(source_script: StubSource, keep_report: bool = True, diff: boo
|
|
192
194
|
|
193
195
|
source_content = ""
|
194
196
|
if isinstance(source_script, Path):
|
195
|
-
source_content = source_script.read_text()
|
197
|
+
source_content = source_script.read_text(encoding="utf-8")
|
196
198
|
elif isinstance(source_script, (StringIO, TextIOWrapper)):
|
197
199
|
source_content = "".join(source_script.readlines())
|
198
200
|
elif isinstance(source_script, str): # type: ignore
|
199
201
|
source_content = source_script
|
200
202
|
else:
|
201
|
-
raise TypeError(
|
202
|
-
f"source_script must be str, Path, or file-like object, not {type(source_script)}"
|
203
|
-
)
|
203
|
+
raise TypeError(f"source_script must be str, Path, or file-like object, not {type(source_script)}")
|
204
204
|
|
205
205
|
if not source_content:
|
206
206
|
raise ValueError("No source content")
|
207
|
+
len_1 = len(source_content)
|
208
|
+
|
209
|
+
if 0:
|
210
|
+
min_source = reduce_log_print(keep_report, diff, source_content)
|
211
|
+
else:
|
212
|
+
min_source = source_content
|
213
|
+
len_2 = len(min_source)
|
214
|
+
|
215
|
+
min_source = python_minifier.minify(
|
216
|
+
min_source,
|
217
|
+
filename=getattr(source_script, "name", None),
|
218
|
+
combine_imports=True,
|
219
|
+
remove_literal_statements=True, # no Docstrings
|
220
|
+
remove_annotations=True, # not used runtime anyways
|
221
|
+
hoist_literals=True, # remove redundant strings
|
222
|
+
rename_locals=True, # short names save memory
|
223
|
+
preserve_locals=["stubber", "path"], # names to keep
|
224
|
+
rename_globals=True, # short names save memory
|
225
|
+
# keep these globals to allow testing/mocking to work against the minified not compiled version
|
226
|
+
preserve_globals=[
|
227
|
+
"main",
|
228
|
+
"Stubber",
|
229
|
+
"read_path",
|
230
|
+
"get_root",
|
231
|
+
"_info",
|
232
|
+
"os",
|
233
|
+
"sys",
|
234
|
+
"__version__",
|
235
|
+
],
|
236
|
+
# remove_pass=True, # no dead code
|
237
|
+
# convert_posargs_to_args=True, # Does not save any space
|
238
|
+
)
|
239
|
+
len_3 = len(min_source)
|
240
|
+
if 1:
|
241
|
+
# write to temp file for debugging
|
242
|
+
with open("tmp_minified.py", "w+") as f:
|
243
|
+
f.write(min_source)
|
244
|
+
|
245
|
+
log.info(f"Original length : {len_1}")
|
246
|
+
log.info(f"Reduced length : {len_2}")
|
247
|
+
log.info(f"Minified length : {len_3}")
|
248
|
+
log.info(f"Reduced by : {len_1-len_3} ")
|
249
|
+
return min_source
|
207
250
|
|
251
|
+
|
252
|
+
def reduce_log_print(keep_report, diff, source_content):
|
208
253
|
edits: LineEdits = [
|
209
254
|
("keepprint", "print('Debug: "),
|
210
255
|
("keepprint", "print('DEBUG: "),
|
@@ -250,40 +295,7 @@ def minify_script(source_script: StubSource, keep_report: bool = True, diff: boo
|
|
250
295
|
] + edits
|
251
296
|
|
252
297
|
content = edit_lines(source_content, edits, diff=diff)
|
253
|
-
|
254
|
-
if 1:
|
255
|
-
# write to temp file for debugging
|
256
|
-
with open("tmp_minified.py", "w+") as f:
|
257
|
-
f.write(content)
|
258
|
-
|
259
|
-
source = python_minifier.minify(
|
260
|
-
content,
|
261
|
-
filename=getattr(source_script, "name", None),
|
262
|
-
combine_imports=True,
|
263
|
-
remove_literal_statements=True, # no Docstrings
|
264
|
-
remove_annotations=True, # not used runtime anyways
|
265
|
-
hoist_literals=True, # remove redundant strings
|
266
|
-
rename_locals=True, # short names save memory
|
267
|
-
preserve_locals=["stubber", "path"], # names to keep
|
268
|
-
rename_globals=True, # short names save memory
|
269
|
-
# keep these globals to allow testing/mocking to work against the minified not compiled version
|
270
|
-
preserve_globals=[
|
271
|
-
"main",
|
272
|
-
"Stubber",
|
273
|
-
"read_path",
|
274
|
-
"get_root",
|
275
|
-
"_info",
|
276
|
-
"os",
|
277
|
-
"sys",
|
278
|
-
"__version__",
|
279
|
-
],
|
280
|
-
# remove_pass=True, # no dead code
|
281
|
-
# convert_posargs_to_args=True, # Does not save any space
|
282
|
-
)
|
283
|
-
log.debug(f"Original length : {len(content)}")
|
284
|
-
log.info(f"Minified length : {len(source)}")
|
285
|
-
log.info(f"Reduced by : {len(content)-len(source)} ")
|
286
|
-
return source
|
298
|
+
return content
|
287
299
|
|
288
300
|
|
289
301
|
def minify(
|
@@ -347,11 +359,10 @@ def cross_compile(
|
|
347
359
|
else:
|
348
360
|
# target must be a Path object
|
349
361
|
_target = get_temp_file(suffix=".mpy")
|
350
|
-
|
351
362
|
result = pipx_mpy_cross(version, source_file, _target)
|
352
363
|
if result.stderr and "No matching distribution found for mpy-cross==" in result.stderr:
|
353
364
|
log.warning(f"mpy-cross=={version} not found, using latest")
|
354
|
-
result = pipx_mpy_cross(
|
365
|
+
result = pipx_mpy_cross(V_PREVIEW, source_file, _target)
|
355
366
|
|
356
367
|
if result.returncode == 0:
|
357
368
|
log.debug(f"mpy-cross compiled to : {_target.name}")
|
@@ -367,9 +378,11 @@ def cross_compile(
|
|
367
378
|
return result.returncode
|
368
379
|
|
369
380
|
|
370
|
-
def pipx_mpy_cross(version, source_file, _target):
|
381
|
+
def pipx_mpy_cross(version: str, source_file, _target):
|
371
382
|
"""Run mpy-cross using pipx"""
|
372
|
-
|
383
|
+
|
384
|
+
log.info(f"Compiling with mpy-cross version: {version}")
|
385
|
+
if version in SET_PREVIEW:
|
373
386
|
version = ""
|
374
387
|
if version:
|
375
388
|
version = "==" + version
|
@@ -378,7 +391,7 @@ def pipx_mpy_cross(version, source_file, _target):
|
|
378
391
|
# Add params
|
379
392
|
cmd += ["-O2", str(source_file), "-o", str(_target), "-s", "createstubs.py"]
|
380
393
|
log.trace(" ".join(cmd))
|
381
|
-
result = subprocess.run(cmd, capture_output=True, text=True)
|
394
|
+
result = subprocess.run(cmd, capture_output=True, text=True, encoding="utf-8") # Specify the encoding
|
382
395
|
return result
|
383
396
|
|
384
397
|
|
stubber/publish/candidates.py
CHANGED
@@ -10,7 +10,6 @@ what versions are available. This module provides functions to :
|
|
10
10
|
- get a list of the firmware/board stubs (firmware candidates)
|
11
11
|
"""
|
12
12
|
|
13
|
-
|
14
13
|
import re
|
15
14
|
from pathlib import Path
|
16
15
|
from typing import Any, Dict, Generator, List, Optional, Union
|
@@ -18,15 +17,11 @@ from typing import Any, Dict, Generator, List, Optional, Union
|
|
18
17
|
from packaging.version import parse
|
19
18
|
|
20
19
|
import stubber.basicgit as git
|
21
|
-
from stubber
|
20
|
+
from stubber import utils
|
22
21
|
from stubber.publish.defaults import GENERIC, GENERIC_L, GENERIC_U
|
22
|
+
from stubber.publish.enums import COMBO_STUBS, DOC_STUBS, FIRMWARE_STUBS
|
23
23
|
from stubber.utils.config import CONFIG
|
24
|
-
from stubber.utils.versions import clean_version, micropython_versions
|
25
|
-
|
26
|
-
OLDEST_VERSION = "1.16"
|
27
|
-
"This is the oldest MicroPython version to build the stubs on"
|
28
|
-
|
29
|
-
V_LATEST = "latest"
|
24
|
+
from stubber.utils.versions import OLDEST_VERSION, SET_PREVIEW, V_PREVIEW, clean_version, micropython_versions
|
30
25
|
|
31
26
|
|
32
27
|
def subfolder_names(path: Path):
|
@@ -50,13 +45,13 @@ def version_candidates(
|
|
50
45
|
for name in subfolder_names(path):
|
51
46
|
if match := re.match(folder_re, name):
|
52
47
|
folder_ver = clean_version(match[1])
|
53
|
-
if folder_ver ==
|
48
|
+
if folder_ver == V_PREVIEW or parse(folder_ver) >= parse(oldest):
|
54
49
|
yield folder_ver
|
55
50
|
|
56
51
|
|
57
52
|
def list_frozen_ports(
|
58
53
|
family: str = "micropython",
|
59
|
-
version: str =
|
54
|
+
version: str = V_PREVIEW,
|
60
55
|
path: Path = CONFIG.stub_path,
|
61
56
|
):
|
62
57
|
"get list of ports with frozen stubs for a given family and version"
|
@@ -94,7 +89,7 @@ def list_micropython_port_boards(
|
|
94
89
|
|
95
90
|
def frozen_candidates(
|
96
91
|
family: str = "micropython",
|
97
|
-
versions: Union[str, List[str]] =
|
92
|
+
versions: Union[str, List[str]] = V_PREVIEW,
|
98
93
|
ports: Union[str, List[str]] = "all",
|
99
94
|
boards: Union[str, List[str]] = "all",
|
100
95
|
*,
|
@@ -111,7 +106,7 @@ def frozen_candidates(
|
|
111
106
|
auto_port = is_auto(ports)
|
112
107
|
auto_board = is_auto(boards)
|
113
108
|
if is_auto(versions):
|
114
|
-
versions = list(version_candidates(suffix="frozen", prefix=family, path=path)) + [
|
109
|
+
versions = list(version_candidates(suffix="frozen", prefix=family, path=path)) + [V_PREVIEW]
|
115
110
|
else:
|
116
111
|
versions = [versions] if isinstance(versions, str) else versions
|
117
112
|
|
@@ -129,9 +124,7 @@ def frozen_candidates(
|
|
129
124
|
# lookup the (frozen) micropython ports
|
130
125
|
ports = list_frozen_ports(family, version, path=path)
|
131
126
|
else:
|
132
|
-
raise NotImplementedError(
|
133
|
-
f"auto ports not implemented for family {family}"
|
134
|
-
) # pragma: no cover
|
127
|
+
raise NotImplementedError(f"auto ports not implemented for family {family}") # pragma: no cover
|
135
128
|
# elif family == "pycom":
|
136
129
|
# ports = ["esp32"]
|
137
130
|
# elif family == "lobo":
|
@@ -164,9 +157,7 @@ def frozen_candidates(
|
|
164
157
|
|
165
158
|
else:
|
166
159
|
# raise NotImplementedError(f"auto boards not implemented for family {family}") # pragma: no cover
|
167
|
-
raise NotImplementedError(
|
168
|
-
f"auto boards not implemented for family {family}"
|
169
|
-
) # pragma: no cover
|
160
|
+
raise NotImplementedError(f"auto boards not implemented for family {family}") # pragma: no cover
|
170
161
|
# elif family == "pycom":
|
171
162
|
# boards = ["wipy", "lopy", "gpy", "fipy"]
|
172
163
|
# ---------------------------------------------------------------------------
|
@@ -199,7 +190,7 @@ def is_auto(thing: Union[None, str, List[str]]):
|
|
199
190
|
|
200
191
|
def docstub_candidates(
|
201
192
|
family: str = "micropython",
|
202
|
-
versions: Union[str, List[str]] =
|
193
|
+
versions: Union[str, List[str]] = V_PREVIEW,
|
203
194
|
path: Path = CONFIG.stub_path,
|
204
195
|
):
|
205
196
|
"""
|
@@ -220,7 +211,7 @@ def docstub_candidates(
|
|
220
211
|
|
221
212
|
def board_candidates(
|
222
213
|
family: str = "micropython",
|
223
|
-
versions: Union[str, List[str]] =
|
214
|
+
versions: Union[str, List[str]] = V_PREVIEW,
|
224
215
|
*,
|
225
216
|
mpy_path: Path = CONFIG.mpy_path,
|
226
217
|
pt: str = FIRMWARE_STUBS,
|
@@ -237,8 +228,10 @@ def board_candidates(
|
|
237
228
|
|
238
229
|
for version in versions:
|
239
230
|
# check out the micropython repo for this version
|
240
|
-
if version in
|
231
|
+
if version in SET_PREVIEW:
|
241
232
|
r = git.switch_branch(repo=mpy_path, branch="master")
|
233
|
+
# get the current checked out version
|
234
|
+
version = utils.checkedout_version(mpy_path)
|
242
235
|
else:
|
243
236
|
r = git.checkout_tag(repo=mpy_path, tag=version)
|
244
237
|
if not r:
|
@@ -283,7 +276,6 @@ def filter_list(
|
|
283
276
|
worklist = [
|
284
277
|
i
|
285
278
|
for i in worklist
|
286
|
-
if i["board"].lower() in boards_
|
287
|
-
or i["board"].lower().replace("generic_", "") in boards_
|
279
|
+
if i["board"].lower() in boards_ or i["board"].lower().replace("generic_", "") in boards_
|
288
280
|
]
|
289
281
|
return worklist
|
stubber/publish/defaults.py
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
from typing import Dict, List
|
3
3
|
|
4
4
|
from stubber.utils.config import CONFIG
|
5
|
-
from stubber.utils.versions import clean_version
|
5
|
+
from stubber.utils.versions import V_PREVIEW, clean_version
|
6
6
|
|
7
7
|
# The default board for the ports modules documented with base name only
|
8
8
|
# as the MicroPython BOARD naming convention has changed over time there are different options to try
|
@@ -24,7 +24,7 @@ GENERIC = {GENERIC_L, GENERIC_U}
|
|
24
24
|
"GENERIC eithercase"
|
25
25
|
|
26
26
|
|
27
|
-
def default_board(port: str, version=
|
27
|
+
def default_board(port: str, version=V_PREVIEW) -> str: # sourcery skip: assign-if-exp
|
28
28
|
"""Return the default board for the given version and port"""
|
29
29
|
ver_flat = clean_version(version, flat=True)
|
30
30
|
if port in DEFAULT_BOARDS:
|
@@ -49,9 +49,7 @@ def merge_all_docstubs(
|
|
49
49
|
for candidate in candidates:
|
50
50
|
# use the default board for the port
|
51
51
|
if candidate["board"] in GENERIC:
|
52
|
-
candidate["board"] = default_board(
|
53
|
-
port=candidate["port"], version=candidate["version"]
|
54
|
-
)
|
52
|
+
candidate["board"] = default_board(port=candidate["port"], version=candidate["version"])
|
55
53
|
# check if we have board stubs of this version and port
|
56
54
|
doc_path = CONFIG.stub_path / f"{get_base(candidate)}-docstubs"
|
57
55
|
# src and dest paths
|
@@ -120,13 +118,13 @@ def copy_and_merge_docstubs(fw_path: Path, dest_path: Path, docstub_path: Path):
|
|
120
118
|
"pycopy_imphook", # is not intended to be used directly, and has an unresolved subclass
|
121
119
|
]:
|
122
120
|
for suffix in [".py", ".pyi"]:
|
123
|
-
if (dest_path / name).with_suffix(suffix).exists():
|
124
|
-
(dest_path / name).with_suffix(suffix).unlink()
|
121
|
+
if (dest_path / name).with_suffix(suffix).exists(): # type: ignore
|
122
|
+
(dest_path / name).with_suffix(suffix).unlink() # type: ignore
|
125
123
|
|
126
124
|
# 2 - Enrich the firmware stubs with the document stubs
|
127
125
|
result = enrich_folder(dest_path, docstub_path=docstub_path, write_back=True)
|
128
126
|
|
129
127
|
# copy the docstubs manifest.json file to the package folder
|
130
|
-
|
131
|
-
|
128
|
+
if (docstub_path / "modules.json").exists():
|
129
|
+
shutil.copy(docstub_path / "modules.json", dest_path / "doc_stubs.json")
|
132
130
|
return result
|
@@ -27,7 +27,7 @@ def add_machine_pin_call(merged_path: Path, version: str):
|
|
27
27
|
log.error(f"no docstubs found for {version}")
|
28
28
|
return False
|
29
29
|
log.trace(f"Parsing {mod_path} for __call__ method")
|
30
|
-
source = mod_path.read_text()
|
30
|
+
source = mod_path.read_text(encoding="utf-8")
|
31
31
|
module = cst.parse_module(source)
|
32
32
|
|
33
33
|
call_finder = CallFinder()
|
@@ -40,7 +40,7 @@ def add_machine_pin_call(merged_path: Path, version: str):
|
|
40
40
|
# then use the CallAdder to add the __call__ method to all machine and pyb stubs
|
41
41
|
mod_paths = [f for f in merged_path.rglob("*.*") if f.stem in {"machine", "umachine", "pyb"}]
|
42
42
|
for mod_path in mod_paths:
|
43
|
-
source = mod_path.read_text()
|
43
|
+
source = mod_path.read_text(encoding="utf-8")
|
44
44
|
machine_module = cst.parse_module(source)
|
45
45
|
new_module = machine_module.visit(CallAdder(call_finder.call_meth))
|
46
46
|
mod_path.write_text(new_module.code)
|
stubber/publish/pathnames.py
CHANGED
@@ -11,7 +11,7 @@ from loguru import logger as log
|
|
11
11
|
from stubber.publish.defaults import default_board
|
12
12
|
from stubber.publish.package import GENERIC
|
13
13
|
from stubber.utils.config import CONFIG
|
14
|
-
from stubber.utils.versions import clean_version
|
14
|
+
from stubber.utils.versions import V_PREVIEW, clean_version
|
15
15
|
|
16
16
|
|
17
17
|
## Helper functions
|
@@ -40,7 +40,7 @@ def board_folder_name(fw: Dict, *, version: Optional[str] = None) -> str:
|
|
40
40
|
|
41
41
|
def get_board_path(candidate: Dict) -> Path:
|
42
42
|
board_path = CONFIG.stub_path / board_folder_name(candidate)
|
43
|
-
if candidate["version"]
|
43
|
+
if V_PREVIEW in candidate["version"] and not board_path.exists():
|
44
44
|
log.debug(f"no board stubs found for {candidate['version']}, trying stable")
|
45
45
|
board_path = CONFIG.stub_path / board_folder_name(candidate, version=CONFIG.stable_version)
|
46
46
|
|
stubber/publish/publish.py
CHANGED
@@ -13,11 +13,12 @@ from stubber.publish.defaults import GENERIC_U
|
|
13
13
|
from stubber.publish.enums import COMBO_STUBS
|
14
14
|
from stubber.publish.package import get_package
|
15
15
|
from stubber.utils.config import CONFIG
|
16
|
+
from stubber.utils.versions import V_PREVIEW
|
16
17
|
|
17
18
|
|
18
19
|
def build_multiple(
|
19
20
|
family: str = "micropython",
|
20
|
-
versions: List[str] = [
|
21
|
+
versions: List[str] = [V_PREVIEW],
|
21
22
|
ports: List[str] = ["all"],
|
22
23
|
boards: List[str] = [GENERIC_U],
|
23
24
|
production: bool = False,
|
stubber/publish/stubpackage.py
CHANGED
@@ -29,7 +29,7 @@ from stubber.publish.defaults import GENERIC_U, default_board
|
|
29
29
|
from stubber.publish.enums import StubSource
|
30
30
|
from stubber.publish.pypi import Version, get_pypi_versions
|
31
31
|
from stubber.utils.config import CONFIG
|
32
|
-
from stubber.utils.versions import clean_version
|
32
|
+
from stubber.utils.versions import SET_PREVIEW, V_PREVIEW, clean_version
|
33
33
|
|
34
34
|
Status = NewType("Status", Dict[str, Union[str, None]])
|
35
35
|
StubSources = List[Tuple[StubSource, Path]]
|
@@ -108,7 +108,7 @@ class VersionedPackage(object):
|
|
108
108
|
return self._get_next_package_version(production)
|
109
109
|
|
110
110
|
def is_preview(self):
|
111
|
-
return self.mpy_version
|
111
|
+
return self.mpy_version in SET_PREVIEW or V_PREVIEW in self.mpy_version
|
112
112
|
|
113
113
|
def _get_next_preview_package_version(self, production: bool = False) -> str:
|
114
114
|
"""
|
@@ -125,17 +125,9 @@ class VersionedPackage(object):
|
|
125
125
|
parts = describe.split("-", 3)
|
126
126
|
ver = parts[0]
|
127
127
|
if len(parts) > 1:
|
128
|
-
rc = (
|
129
|
-
parts[1]
|
130
|
-
if parts[1].isdigit()
|
131
|
-
else parts[2]
|
132
|
-
if len(parts) > 2 and parts[2].isdigit()
|
133
|
-
else 1
|
134
|
-
)
|
128
|
+
rc = parts[1] if parts[1].isdigit() else parts[2] if len(parts) > 2 and parts[2].isdigit() else 1
|
135
129
|
rc = int(rc)
|
136
|
-
base = (
|
137
|
-
bump_version(Version(ver), minor_bump=True) if parts[1] != "preview" else Version(ver)
|
138
|
-
)
|
130
|
+
base = bump_version(Version(ver), minor_bump=True) if parts[1] != V_PREVIEW else Version(ver)
|
139
131
|
return str(bump_version(base, rc=rc))
|
140
132
|
# raise ValueError("cannot determine next version number micropython")
|
141
133
|
|
@@ -312,9 +304,7 @@ class Builder(VersionedPackage):
|
|
312
304
|
# Check if all stub source folders exist
|
313
305
|
for stub_type, src_path in self.stub_sources:
|
314
306
|
if not (CONFIG.stub_path / src_path).exists():
|
315
|
-
raise FileNotFoundError(
|
316
|
-
f"Could not find stub source folder {CONFIG.stub_path / src_path}"
|
317
|
-
)
|
307
|
+
raise FileNotFoundError(f"Could not find stub source folder {CONFIG.stub_path / src_path}")
|
318
308
|
|
319
309
|
# 1 - Copy the stubs to the package, directly in the package folder (no folders)
|
320
310
|
# for stub_type, fw_path in [s for s in self.stub_sources]:
|
@@ -325,9 +315,7 @@ class Builder(VersionedPackage):
|
|
325
315
|
self.copy_folder(stub_type, src_path)
|
326
316
|
except OSError as e:
|
327
317
|
if stub_type != StubSource.FROZEN:
|
328
|
-
raise FileNotFoundError(
|
329
|
-
f"Could not find stub source folder {src_path}"
|
330
|
-
) from e
|
318
|
+
raise FileNotFoundError(f"Could not find stub source folder {src_path}") from e
|
331
319
|
else:
|
332
320
|
log.debug(f"Error copying stubs from : {CONFIG.stub_path / src_path}, {e}")
|
333
321
|
finally:
|
@@ -594,7 +582,7 @@ class PoetryBuilder(Builder):
|
|
594
582
|
with open(_toml, "rb") as f:
|
595
583
|
pyproject = tomllib.load(f)
|
596
584
|
ver = pyproject["tool"]["poetry"]["version"]
|
597
|
-
return str(parse(ver)) if ver
|
585
|
+
return str(parse(ver)) if ver not in SET_PREVIEW else ver
|
598
586
|
|
599
587
|
@pkg_version.setter
|
600
588
|
def pkg_version(self, version: str) -> None:
|
@@ -654,6 +642,7 @@ class PoetryBuilder(Builder):
|
|
654
642
|
# stdout=subprocess.PIPE,
|
655
643
|
stdout=subprocess.PIPE, # interestingly: errors on stdout , output on stderr .....
|
656
644
|
universal_newlines=True,
|
645
|
+
encoding="utf-8",
|
657
646
|
)
|
658
647
|
log.trace(f"poetry {parameters} completed")
|
659
648
|
except (NotADirectoryError, FileNotFoundError) as e: # pragma: no cover # InvalidVersion
|
@@ -718,8 +707,7 @@ class PoetryBuilder(Builder):
|
|
718
707
|
_pyproject = self.pyproject
|
719
708
|
assert _pyproject is not None, "No pyproject.toml file found"
|
720
709
|
_pyproject["tool"]["poetry"]["packages"] = [
|
721
|
-
{"include": p.relative_to(self.package_path).as_posix()}
|
722
|
-
for p in sorted((self.package_path).rglob("*.pyi"))
|
710
|
+
{"include": p.relative_to(self.package_path).as_posix()} for p in sorted((self.package_path).rglob("*.pyi"))
|
723
711
|
]
|
724
712
|
# write out the pyproject.toml file
|
725
713
|
self.pyproject = _pyproject
|
@@ -862,9 +850,7 @@ class StubPackage(PoetryBuilder):
|
|
862
850
|
# check if the sources exist
|
863
851
|
ok = self.are_package_sources_available()
|
864
852
|
if not ok:
|
865
|
-
log.debug(
|
866
|
-
f"{self.package_name}: skipping as one or more source stub folders are missing"
|
867
|
-
)
|
853
|
+
log.debug(f"{self.package_name}: skipping as one or more source stub folders are missing")
|
868
854
|
self.status["error"] = "Skipped, stub folder(s) missing"
|
869
855
|
shutil.rmtree(self.package_path.as_posix())
|
870
856
|
self._publish = False # type: ignore
|
@@ -886,9 +872,7 @@ class StubPackage(PoetryBuilder):
|
|
886
872
|
self,
|
887
873
|
production: bool, # PyPI or Test-PyPi - USED TO FIND THE NEXT VERSION NUMBER
|
888
874
|
force=False, # BUILD even if no changes
|
889
|
-
) ->
|
890
|
-
bool
|
891
|
-
): # sourcery skip: default-mutable-arg, extract-duplicate-method, require-parameter-annotation
|
875
|
+
) -> bool: # sourcery skip: default-mutable-arg, extract-duplicate-method, require-parameter-annotation
|
892
876
|
"""
|
893
877
|
Build a package
|
894
878
|
look up the previous package version in the dabase
|
@@ -908,14 +892,14 @@ class StubPackage(PoetryBuilder):
|
|
908
892
|
if not self.status["error"]:
|
909
893
|
self.status["error"] = "Could not build/update package"
|
910
894
|
return False
|
911
|
-
# If there are changes to the package, then publish it
|
912
|
-
if self.is_changed():
|
913
|
-
log.info(f"Found changes to package sources: {self.package_name} {self.pkg_version} ")
|
914
|
-
log.trace(f"Old hash {self.hash} != New hash {self.calculate_hash()}")
|
915
|
-
elif force:
|
916
|
-
log.info(f"Force build: {self.package_name} {self.pkg_version} ")
|
917
895
|
|
896
|
+
# If there are changes to the package, then publish it
|
918
897
|
if self.is_changed() or force:
|
898
|
+
if force:
|
899
|
+
log.info(f"Force build: {self.package_name} {self.pkg_version} ")
|
900
|
+
else:
|
901
|
+
log.info(f"Found changes to package sources: {self.package_name} {self.pkg_version} ")
|
902
|
+
log.trace(f"Old hash {self.hash} != New hash {self.calculate_hash()}")
|
919
903
|
# Build the distribution files
|
920
904
|
old_ver = self.pkg_version
|
921
905
|
self.pkg_version = self.next_package_version(production)
|
@@ -975,10 +959,8 @@ class StubPackage(PoetryBuilder):
|
|
975
959
|
self.next_package_version(production=production)
|
976
960
|
# Publish the package to PyPi, Test-PyPi or Github
|
977
961
|
if self.is_changed():
|
978
|
-
if self.mpy_version
|
979
|
-
log.warning(
|
980
|
-
"version: `latest` package will only be available on Github, and not published to PyPi."
|
981
|
-
)
|
962
|
+
if self.mpy_version in SET_PREVIEW and production and not force:
|
963
|
+
log.warning("version: `latest` package will only be available on Github, and not published to PyPi.")
|
982
964
|
self.status["result"] = "Published to GitHub"
|
983
965
|
else:
|
984
966
|
return self.publish_distribution(dry_run, production, db)
|
@@ -1007,9 +989,7 @@ class StubPackage(PoetryBuilder):
|
|
1007
989
|
if not dry_run:
|
1008
990
|
pub_ok = self.poetry_publish(production=production)
|
1009
991
|
else:
|
1010
|
-
log.warning(
|
1011
|
-
f"{self.package_name}: Dry run, not publishing to {'' if production else 'Test-'}PyPi"
|
1012
|
-
)
|
992
|
+
log.warning(f"{self.package_name}: Dry run, not publishing to {'' if production else 'Test-'}PyPi")
|
1013
993
|
pub_ok = True
|
1014
994
|
if not pub_ok:
|
1015
995
|
log.warning(f"{self.package_name}: Publish failed for {self.pkg_version}")
|
stubber/rst/lookup.py
CHANGED
@@ -20,6 +20,7 @@ __all__ = [
|
|
20
20
|
|
21
21
|
# all possible Types needed for the stubs - exxess types should be removed later , and otherwise won't do much harm
|
22
22
|
TYPING_IMPORT: List[str] = [
|
23
|
+
"from __future__ import annotations",
|
23
24
|
"from typing import IO, Any, Callable, Coroutine, Dict, Generator, Iterator, List, NoReturn, Optional, Tuple, Union, NamedTuple, TypeVar",
|
24
25
|
"from _typeshed import Incomplete",
|
25
26
|
]
|
@@ -483,17 +484,18 @@ PARAM_FIXES = [
|
|
483
484
|
# List of classes and their parent classes that should be added to the class definition
|
484
485
|
CHILD_PARENT_CLASS = {
|
485
486
|
# machine
|
486
|
-
#
|
487
|
+
# SoftSPI is defined before SPI, so baseclass is not yet available - but in a .pyi that is OK
|
488
|
+
"SoftSPI": "SPI",
|
487
489
|
"SoftI2C": "I2C",
|
488
490
|
"Switch": "Pin",
|
489
491
|
"Signal": "Pin",
|
490
492
|
# uio # unclear regarding deprecation in python 3.12
|
491
493
|
# "IOBase": "IO", # DOCME not in documentation
|
492
|
-
"TextIOWrapper": "IO",
|
493
|
-
"FileIO": "IO",
|
494
|
-
"StringIO": "IO",
|
495
|
-
"BytesIO": "IO",
|
496
|
-
"BufferedWriter": "IOBase", # DOCME: not in documentation
|
494
|
+
"TextIOWrapper": "IO", # "TextIOBase, TextIO", # based on Stdlib
|
495
|
+
"FileIO": "IO", # "RawIOBase, BinaryIO", # based on Stdlib
|
496
|
+
"StringIO": "IO", # "BufferedIOBase, BinaryIO", # based on Stdlib
|
497
|
+
"BytesIO": "IO", # "BufferedIOBase, BinaryIO", # based on Stdlib
|
498
|
+
"BufferedWriter": "IOBase", # DOCME: not in documentation # "BufferedWriter": "BufferedIOBase", # based on Stdlib
|
497
499
|
# uzlib
|
498
500
|
# "DecompIO": "IO", # https://docs.python.org/3/library/typing.html#other-concrete-types
|
499
501
|
# -------------------------------------------------------------------------------------
|
@@ -512,7 +514,7 @@ CHILD_PARENT_CLASS = {
|
|
512
514
|
"namedtuple": "tuple",
|
513
515
|
"deque": "stdlib_deque",
|
514
516
|
# ESPNow
|
515
|
-
"ESPNow": "ESPNowBase,Iterator",
|
517
|
+
"ESPNow": "ESPNowBase,Iterator", # causes issue with mypy
|
516
518
|
"AIOESPNow": "ESPNow",
|
517
519
|
# array
|
518
520
|
"array": "List",
|