micropython-stubber 1.20.5__py3-none-any.whl → 1.23.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.
Files changed (152) hide show
  1. {micropython_stubber-1.20.5.dist-info → micropython_stubber-1.23.0.dist-info}/LICENSE +30 -30
  2. {micropython_stubber-1.20.5.dist-info → micropython_stubber-1.23.0.dist-info}/METADATA +1 -1
  3. micropython_stubber-1.23.0.dist-info/RECORD +159 -0
  4. mpflash/README.md +184 -184
  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/bootloader/__init__.py +37 -36
  9. mpflash/mpflash/bootloader/manual.py +102 -102
  10. mpflash/mpflash/bootloader/micropython.py +10 -10
  11. mpflash/mpflash/bootloader/touch1200.py +45 -45
  12. mpflash/mpflash/cli_download.py +129 -129
  13. mpflash/mpflash/cli_flash.py +219 -219
  14. mpflash/mpflash/cli_group.py +98 -98
  15. mpflash/mpflash/cli_list.py +81 -81
  16. mpflash/mpflash/cli_main.py +41 -41
  17. mpflash/mpflash/common.py +164 -164
  18. mpflash/mpflash/config.py +43 -47
  19. mpflash/mpflash/connected.py +74 -74
  20. mpflash/mpflash/download.py +360 -360
  21. mpflash/mpflash/downloaded.py +130 -129
  22. mpflash/mpflash/errors.py +9 -9
  23. mpflash/mpflash/flash.py +55 -52
  24. mpflash/mpflash/flash_esp.py +59 -59
  25. mpflash/mpflash/flash_stm32.py +18 -24
  26. mpflash/mpflash/flash_stm32_cube.py +111 -111
  27. mpflash/mpflash/flash_stm32_dfu.py +104 -101
  28. mpflash/mpflash/flash_uf2.py +89 -67
  29. mpflash/mpflash/flash_uf2_boardid.py +15 -15
  30. mpflash/mpflash/flash_uf2_linux.py +129 -123
  31. mpflash/mpflash/flash_uf2_macos.py +37 -34
  32. mpflash/mpflash/flash_uf2_windows.py +38 -34
  33. mpflash/mpflash/list.py +89 -89
  34. mpflash/mpflash/logger.py +41 -41
  35. mpflash/mpflash/mpboard_id/__init__.py +93 -93
  36. mpflash/mpflash/mpboard_id/add_boards.py +255 -255
  37. mpflash/mpflash/mpboard_id/board.py +37 -37
  38. mpflash/mpflash/mpboard_id/board_id.py +86 -86
  39. mpflash/mpflash/mpboard_id/store.py +43 -43
  40. mpflash/mpflash/mpremoteboard/__init__.py +226 -221
  41. mpflash/mpflash/mpremoteboard/mpy_fw_info.py +141 -141
  42. mpflash/mpflash/mpremoteboard/runner.py +140 -140
  43. mpflash/mpflash/uf2disk.py +12 -12
  44. mpflash/mpflash/vendor/basicgit.py +288 -288
  45. mpflash/mpflash/vendor/click_aliases.py +91 -91
  46. mpflash/mpflash/vendor/dfu.py +165 -165
  47. mpflash/mpflash/vendor/pydfu.py +605 -605
  48. mpflash/mpflash/vendor/readme.md +2 -2
  49. mpflash/mpflash/vendor/versions.py +119 -117
  50. mpflash/mpflash/worklist.py +171 -170
  51. mpflash/poetry.lock +1588 -1588
  52. mpflash/pyproject.toml +64 -60
  53. mpflash/stm32_udev_rules.md +62 -62
  54. stubber/__init__.py +3 -3
  55. stubber/basicgit.py +294 -288
  56. stubber/board/board_info.csv +193 -193
  57. stubber/board/boot.py +34 -34
  58. stubber/board/createstubs.py +986 -986
  59. stubber/board/createstubs_db.py +825 -825
  60. stubber/board/createstubs_db_min.py +331 -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 +766 -766
  65. stubber/board/createstubs_mem_min.py +306 -306
  66. stubber/board/createstubs_mem_mpy.mpy +0 -0
  67. stubber/board/createstubs_min.py +294 -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 +454 -454
  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 +145 -145
  83. stubber/codemod/merge_docstub.py +284 -284
  84. stubber/codemod/modify_list.py +54 -54
  85. stubber/codemod/utils.py +57 -57
  86. stubber/commands/build_cmd.py +94 -94
  87. stubber/commands/cli.py +55 -51
  88. stubber/commands/clone_cmd.py +77 -66
  89. stubber/commands/config_cmd.py +29 -29
  90. stubber/commands/enrich_folder_cmd.py +71 -70
  91. stubber/commands/get_core_cmd.py +71 -69
  92. stubber/commands/get_docstubs_cmd.py +89 -87
  93. stubber/commands/get_frozen_cmd.py +114 -112
  94. stubber/commands/get_mcu_cmd.py +61 -56
  95. stubber/commands/merge_cmd.py +67 -66
  96. stubber/commands/publish_cmd.py +119 -119
  97. stubber/commands/stub_cmd.py +31 -30
  98. stubber/commands/switch_cmd.py +62 -54
  99. stubber/commands/variants_cmd.py +49 -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 +36 -36
  107. stubber/freeze/common.py +68 -68
  108. stubber/freeze/freeze_folder.py +69 -69
  109. stubber/freeze/freeze_manifest_2.py +113 -113
  110. stubber/freeze/get_frozen.py +127 -127
  111. stubber/get_cpython.py +101 -101
  112. stubber/get_lobo.py +59 -59
  113. stubber/minify.py +418 -418
  114. stubber/publish/bump.py +86 -86
  115. stubber/publish/candidates.py +262 -262
  116. stubber/publish/database.py +18 -18
  117. stubber/publish/defaults.py +45 -45
  118. stubber/publish/enums.py +24 -24
  119. stubber/publish/helpers.py +29 -29
  120. stubber/publish/merge_docstubs.py +130 -130
  121. stubber/publish/missing_class_methods.py +49 -49
  122. stubber/publish/package.py +146 -146
  123. stubber/publish/pathnames.py +51 -51
  124. stubber/publish/publish.py +120 -120
  125. stubber/publish/pypi.py +38 -38
  126. stubber/publish/stubpackage.py +1029 -1029
  127. stubber/rst/__init__.py +9 -9
  128. stubber/rst/classsort.py +77 -77
  129. stubber/rst/lookup.py +530 -530
  130. stubber/rst/output_dict.py +401 -401
  131. stubber/rst/reader.py +822 -822
  132. stubber/rst/report_return.py +69 -69
  133. stubber/rst/rst_utils.py +540 -540
  134. stubber/stubber.py +38 -38
  135. stubber/stubs_from_docs.py +90 -90
  136. stubber/tools/manifestfile.py +655 -610
  137. stubber/tools/readme.md +7 -6
  138. stubber/update_fallback.py +117 -117
  139. stubber/update_module_list.py +123 -123
  140. stubber/utils/__init__.py +5 -5
  141. stubber/utils/config.py +127 -127
  142. stubber/utils/makeversionhdr.py +54 -54
  143. stubber/utils/manifest.py +92 -92
  144. stubber/utils/post.py +79 -79
  145. stubber/utils/repos.py +157 -154
  146. stubber/utils/stubmaker.py +139 -139
  147. stubber/utils/typed_config_toml.py +77 -77
  148. stubber/utils/versions.py +128 -120
  149. stubber/variants.py +106 -106
  150. micropython_stubber-1.20.5.dist-info/RECORD +0 -159
  151. {micropython_stubber-1.20.5.dist-info → micropython_stubber-1.23.0.dist-info}/WHEEL +0 -0
  152. {micropython_stubber-1.20.5.dist-info → micropython_stubber-1.23.0.dist-info}/entry_points.txt +0 -0
stubber/utils/post.py CHANGED
@@ -1,79 +1,79 @@
1
- """Pre/Post Processing for createstubs.py"""
2
- import subprocess
3
- import sys
4
- from pathlib import Path
5
- from typing import List
6
-
7
- import autoflake
8
- from loguru import logger as log
9
-
10
- from .stubmaker import generate_pyi_files
11
-
12
-
13
- def do_post_processing(stub_paths: List[Path], stubgen: bool, black: bool, autoflake: bool):
14
- "Common post processing"
15
- for path in stub_paths:
16
- if stubgen:
17
- log.debug("Generate type hint files (pyi) in folder: {}".format(path))
18
- generate_pyi_files(path)
19
- if black:
20
- run_black(path)
21
- if autoflake:
22
- run_autoflake(path, process_pyi=True)
23
-
24
-
25
- def run_black(path: Path, capture_output: bool = False):
26
- """
27
- run black to format the code / stubs
28
- """
29
- log.debug("Running black on: {}".format(path))
30
- cmd = [
31
- sys.executable,
32
- "-m",
33
- "black",
34
- path.as_posix(),
35
- "--line-length",
36
- "140",
37
- ]
38
- result = subprocess.run(cmd, capture_output=True, text=True, encoding="utf-8")
39
-
40
- return result.returncode
41
-
42
-
43
- def run_autoflake(path: Path, capture_output: bool = False, process_pyi: bool = False):
44
- """
45
- run autoflake to remove unused imports
46
- needs to be run BEFORE black otherwise it does not recognize long import from`s.
47
- note: is run file-by-file to include processing .pyi files
48
- """
49
- if not path.exists():
50
- log.warning(f"Path does not exist: {path}")
51
- return -1
52
- log.info(f"Running autoflake on: {path}")
53
- # create a list of files to be formatted
54
- files: List[str] = []
55
- files.extend([str(f) for f in path.rglob("*.py")])
56
- if process_pyi:
57
- files.extend([str(f) for f in path.rglob("*.pyi")])
58
-
59
- # build an argument list
60
- autoflake_args = {
61
- "write_to_stdout": False, # print changed text to stdout
62
- "in_place": True, # make changes to files instead of printing diffs
63
- "remove_all_unused_imports": False,
64
- "ignore_init_module_imports": False, # exclude __init__.py when removing unused imports
65
- "expand_star_imports": False,
66
- "remove_duplicate_keys": False,
67
- "remove_unused_variables": False, # remove all unused imports (not just those from the standard library)
68
- "remove_rhs_for_unused_variables": False,
69
- "ignore_pass_statements": False, # remove pass when superfluous
70
- "ignore_pass_after_docstring": False, # ignore pass statements after a newline ending on '"""'
71
- "check": False, # return error code if changes are needed
72
- "check_diff": False,
73
- "quiet": False,
74
- }
75
- # format the files
76
- exit_status = 0
77
- for name in files:
78
- log.debug(f"Running autoflake on: {name}")
79
- exit_status |= autoflake.fix_file(name, args=autoflake_args)
1
+ """Pre/Post Processing for createstubs.py"""
2
+ import subprocess
3
+ import sys
4
+ from pathlib import Path
5
+ from typing import List
6
+
7
+ import autoflake
8
+ from loguru import logger as log
9
+
10
+ from .stubmaker import generate_pyi_files
11
+
12
+
13
+ def do_post_processing(stub_paths: List[Path], stubgen: bool, black: bool, autoflake: bool):
14
+ "Common post processing"
15
+ for path in stub_paths:
16
+ if stubgen:
17
+ log.debug("Generate type hint files (pyi) in folder: {}".format(path))
18
+ generate_pyi_files(path)
19
+ if black:
20
+ run_black(path)
21
+ if autoflake:
22
+ run_autoflake(path, process_pyi=True)
23
+
24
+
25
+ def run_black(path: Path, capture_output: bool = False):
26
+ """
27
+ run black to format the code / stubs
28
+ """
29
+ log.debug("Running black on: {}".format(path))
30
+ cmd = [
31
+ sys.executable,
32
+ "-m",
33
+ "black",
34
+ path.as_posix(),
35
+ "--line-length",
36
+ "140",
37
+ ]
38
+ result = subprocess.run(cmd, capture_output=True, text=True, encoding="utf-8")
39
+
40
+ return result.returncode
41
+
42
+
43
+ def run_autoflake(path: Path, capture_output: bool = False, process_pyi: bool = False):
44
+ """
45
+ run autoflake to remove unused imports
46
+ needs to be run BEFORE black otherwise it does not recognize long import from`s.
47
+ note: is run file-by-file to include processing .pyi files
48
+ """
49
+ if not path.exists():
50
+ log.warning(f"Path does not exist: {path}")
51
+ return -1
52
+ log.info(f"Running autoflake on: {path}")
53
+ # create a list of files to be formatted
54
+ files: List[str] = []
55
+ files.extend([str(f) for f in path.rglob("*.py")])
56
+ if process_pyi:
57
+ files.extend([str(f) for f in path.rglob("*.pyi")])
58
+
59
+ # build an argument list
60
+ autoflake_args = {
61
+ "write_to_stdout": False, # print changed text to stdout
62
+ "in_place": True, # make changes to files instead of printing diffs
63
+ "remove_all_unused_imports": False,
64
+ "ignore_init_module_imports": False, # exclude __init__.py when removing unused imports
65
+ "expand_star_imports": False,
66
+ "remove_duplicate_keys": False,
67
+ "remove_unused_variables": False, # remove all unused imports (not just those from the standard library)
68
+ "remove_rhs_for_unused_variables": False,
69
+ "ignore_pass_statements": False, # remove pass when superfluous
70
+ "ignore_pass_after_docstring": False, # ignore pass statements after a newline ending on '"""'
71
+ "check": False, # return error code if changes are needed
72
+ "check_diff": False,
73
+ "quiet": False,
74
+ }
75
+ # format the files
76
+ exit_status = 0
77
+ for name in files:
78
+ log.debug(f"Running autoflake on: {name}")
79
+ exit_status |= autoflake.fix_file(name, args=autoflake_args)
stubber/utils/repos.py CHANGED
@@ -1,154 +1,157 @@
1
- """ utility functions to handle to cloned repos needed for stubbing."""
2
-
3
- import csv
4
- import os
5
- import pkgutil
6
- import tempfile
7
- from collections import defaultdict
8
- from pathlib import Path
9
- from typing import Tuple
10
-
11
- from loguru import logger as log
12
- from packaging.version import Version
13
-
14
- import stubber.basicgit as git
15
- from stubber.utils.config import CONFIG
16
- from stubber.utils.versions import SET_PREVIEW, V_PREVIEW
17
-
18
- # # log = logging.getLogger(__name__)
19
-
20
-
21
- def switch(tag: str, *, mpy_path: Path, mpy_lib_path: Path):
22
- """
23
- Switch to a specific version of the micropython repos.
24
-
25
- Specify the version with --tag or --version to specify the version tag
26
- of the MicroPython repo.
27
- The Micropython-lib repo will be checked out to a commit that corresponds
28
- in time to that version tag, in order to allow non-current versions to be
29
- stubbed correctly.
30
-
31
- The repros must be cloned already
32
- """
33
- # fetch then switch
34
- git.fetch(mpy_path)
35
- git.fetch(mpy_lib_path)
36
-
37
- if not tag or tag in {"master", ""}:
38
- tag = V_PREVIEW
39
- if tag in SET_PREVIEW:
40
- git.switch_branch(repo=mpy_path, branch="master")
41
- else:
42
- git.checkout_tag(repo=mpy_path, tag=tag)
43
- match_lib_with_mpy(version_tag=tag, mpy_path=mpy_path, lib_path=mpy_lib_path)
44
-
45
-
46
- def read_micropython_lib_commits(filename: str = "data/micropython_tags.csv"):
47
- """
48
- Read a csv with the micropython version and matching micropython-lib commit-hashes
49
- these can be used to make sure that the correct micropython-lib version is checked out.
50
-
51
- filename is relative to the 'stubber' package
52
-
53
- git for-each-ref --sort=creatordate --format '%(refname) %(creatordate)' refs/tags
54
- """
55
- data = pkgutil.get_data("stubber", filename)
56
- if not data:
57
- raise FileNotFoundError(f"Resource {filename} not found")
58
- version_commit = defaultdict() # lgtm [py/multiple-definition]
59
- with tempfile.NamedTemporaryFile(prefix="tags", suffix=".csv", mode="w+t") as ntf:
60
- ntf.file.write(data.decode(encoding="utf8"))
61
- ntf.file.seek(0)
62
- # read the csv file using DictReader
63
- reader = csv.DictReader(ntf.file, skipinitialspace=True) # dialect="excel",
64
- rows = list(reader)
65
- # create a dict version --> commit_hash
66
- version_commit = {
67
- row["version"].split("/")[-1]: row["lib_commit_hash"]
68
- for row in rows
69
- if row["version"].startswith("refs/tags/")
70
- }
71
- # add default
72
- version_commit = defaultdict(lambda: "master", version_commit)
73
- return version_commit
74
-
75
-
76
- def match_lib_with_mpy(version_tag: str, mpy_path: Path, lib_path: Path) -> bool:
77
- micropython_lib_commits = read_micropython_lib_commits()
78
- # Make sure that the correct micropython-lib release is checked out
79
- # check if micropython-lib has matching tags
80
- if version_tag in SET_PREVIEW:
81
- # micropython-lib is now a submodule
82
- result = git.checkout_commit("master", lib_path)
83
- if not result:
84
- log.error("Could not checkout micropython-lib @master")
85
- return False
86
-
87
- return git.sync_submodules(mpy_path)
88
- elif Version(version_tag) >= Version("v1.20.0"):
89
- # micropython-lib is now a submodule
90
- result = git.checkout_tag(version_tag, lib_path)
91
- if not result:
92
- log.warning(f"Could not checkout micropython-lib @{version_tag}")
93
- if not git.checkout_tag("master", lib_path):
94
- log.error("Could not checkout micropython-lib @master")
95
- return False
96
- return git.sync_submodules(mpy_path)
97
- else:
98
- log.info(
99
- f"Matching repo's: Micropython {version_tag} needs micropython-lib:{micropython_lib_commits[version_tag]}"
100
- )
101
- return git.checkout_commit(micropython_lib_commits[version_tag], lib_path)
102
-
103
-
104
- def fetch_repos(tag: str, mpy_path: Path, mpy_lib_path: Path):
105
- """Fetch updates, then switch to the provided tag"""
106
- log.info("fetch updates")
107
- git.fetch(mpy_path)
108
- git.fetch(mpy_lib_path)
109
- try:
110
- git.fetch(CONFIG.mpy_stubs_path)
111
- except Exception:
112
- log.trace("no stubs repo found : {CONFIG.mpy_stubs_path}")
113
-
114
- if not tag:
115
- tag = V_PREVIEW
116
-
117
- log.info(f"Switching to {tag}")
118
- if tag == V_PREVIEW:
119
- git.switch_branch(repo=mpy_path, branch="master")
120
- else:
121
- git.checkout_tag(repo=mpy_path, tag=tag)
122
- result = match_lib_with_mpy(version_tag=tag, mpy_path=mpy_path, lib_path=mpy_lib_path)
123
-
124
- log.info(f"{str(mpy_path):<40} {git.get_local_tag(mpy_path)}")
125
- log.info(f"{str(mpy_lib_path):<40} {git.get_local_tag(mpy_lib_path)}")
126
- try:
127
- sub_mod_path = mpy_path / "lib/micropython-lib"
128
- if (sub_mod_path / ".git").exists():
129
- log.info(f"{str(sub_mod_path):<40} {git.get_local_tag(sub_mod_path)}")
130
- except Exception:
131
- pass
132
- return result
133
-
134
-
135
- def repo_paths(dest_path: Path) -> Tuple[Path, Path]:
136
- """Return the paths to the micropython and micropython-lib repos, given a path to the repos.'"""
137
- if not dest_path.exists():
138
- os.mkdir(dest_path)
139
- # repos are relative to provided path
140
- if dest_path != CONFIG.repo_path:
141
- mpy_path = dest_path / "micropython"
142
- mpy_lib_path = dest_path / "micropython-lib"
143
- else:
144
- mpy_path = CONFIG.mpy_path
145
- mpy_lib_path = CONFIG.mpy_lib_path
146
-
147
- # if no repos then error
148
- if not (mpy_path / ".git").exists():
149
- log.error("micropython repo not found")
150
- raise LookupError
151
- if not (mpy_lib_path / ".git").exists():
152
- log.error("micropython-lib repo not found")
153
- raise LookupError
154
- return mpy_path, mpy_lib_path
1
+ """ utility functions to handle to cloned repos needed for stubbing."""
2
+
3
+ import csv
4
+ import os
5
+ import pkgutil
6
+ import tempfile
7
+ from collections import defaultdict
8
+ from pathlib import Path
9
+ from typing import Tuple
10
+
11
+ from loguru import logger as log
12
+ from packaging.version import Version
13
+
14
+ import stubber.basicgit as git
15
+ from mpflash.vendor.versions import get_stable_mp_version
16
+ from stubber.utils.config import CONFIG
17
+ from stubber.utils.versions import SET_PREVIEW, V_PREVIEW
18
+
19
+ # # log = logging.getLogger(__name__)
20
+
21
+
22
+ def switch(tag: str, *, mpy_path: Path, mpy_lib_path: Path):
23
+ """
24
+ Switch to a specific version of the micropython repos.
25
+
26
+ Specify the version with --tag or --version to specify the version tag
27
+ of the MicroPython repo.
28
+ The Micropython-lib repo will be checked out to a commit that corresponds
29
+ in time to that version tag, in order to allow non-current versions to be
30
+ stubbed correctly.
31
+
32
+ The repros must be cloned already
33
+ """
34
+ # fetch then switch
35
+ git.fetch(mpy_path)
36
+ git.fetch(mpy_lib_path)
37
+
38
+ if not tag or tag in {"master", ""}:
39
+ tag = V_PREVIEW
40
+ if tag in SET_PREVIEW:
41
+ git.switch_branch(repo=mpy_path, branch="master")
42
+ else:
43
+ git.checkout_tag(repo=mpy_path, tag=tag)
44
+ match_lib_with_mpy(version_tag=tag, mpy_path=mpy_path, lib_path=mpy_lib_path)
45
+
46
+
47
+ def read_micropython_lib_commits(filename: str = "data/micropython_tags.csv"):
48
+ """
49
+ Read a csv with the micropython version and matching micropython-lib commit-hashes
50
+ these can be used to make sure that the correct micropython-lib version is checked out.
51
+
52
+ filename is relative to the 'stubber' package
53
+
54
+ git for-each-ref --sort=creatordate --format '%(refname) %(creatordate)' refs/tags
55
+ """
56
+ data = pkgutil.get_data("stubber", filename)
57
+ if not data:
58
+ raise FileNotFoundError(f"Resource {filename} not found")
59
+ version_commit = defaultdict() # lgtm [py/multiple-definition]
60
+ with tempfile.NamedTemporaryFile(prefix="tags", suffix=".csv", mode="w+t") as ntf:
61
+ ntf.file.write(data.decode(encoding="utf8"))
62
+ ntf.file.seek(0)
63
+ # read the csv file using DictReader
64
+ reader = csv.DictReader(ntf.file, skipinitialspace=True) # dialect="excel",
65
+ rows = list(reader)
66
+ # create a dict version --> commit_hash
67
+ version_commit = {
68
+ row["version"].split("/")[-1]: row["lib_commit_hash"]
69
+ for row in rows
70
+ if row["version"].startswith("refs/tags/")
71
+ }
72
+ # add default
73
+ version_commit = defaultdict(lambda: "master", version_commit)
74
+ return version_commit
75
+
76
+
77
+ def match_lib_with_mpy(version_tag: str, mpy_path: Path, lib_path: Path) -> bool:
78
+ micropython_lib_commits = read_micropython_lib_commits()
79
+ # Make sure that the correct micropython-lib release is checked out
80
+ # check if micropython-lib has matching tags
81
+ if version_tag in SET_PREVIEW:
82
+ # micropython-lib is now a submodule
83
+ result = git.checkout_commit("master", lib_path)
84
+ if not result:
85
+ log.error("Could not checkout micropython-lib @master")
86
+ return False
87
+
88
+ return git.sync_submodules(mpy_path)
89
+ elif Version(version_tag) >= Version("v1.20.0"):
90
+ # micropython-lib is now a submodule
91
+ result = git.checkout_tag(version_tag, lib_path)
92
+ if not result:
93
+ log.warning(f"Could not checkout micropython-lib @{version_tag}")
94
+ if not git.checkout_tag("master", lib_path):
95
+ log.error("Could not checkout micropython-lib @master")
96
+ return False
97
+ return git.sync_submodules(mpy_path)
98
+ else:
99
+ log.info(
100
+ f"Matching repo's: Micropython {version_tag} needs micropython-lib:{micropython_lib_commits[version_tag]}"
101
+ )
102
+ return git.checkout_commit(micropython_lib_commits[version_tag], lib_path)
103
+
104
+
105
+ def fetch_repos(tag: str, mpy_path: Path, mpy_lib_path: Path):
106
+ """Fetch updates, then switch to the provided tag"""
107
+ log.info("fetch updates")
108
+ git.fetch(mpy_path)
109
+ git.fetch(mpy_lib_path)
110
+ try:
111
+ git.fetch(CONFIG.mpy_stubs_path)
112
+ except Exception:
113
+ log.trace("no stubs repo found : {CONFIG.mpy_stubs_path}")
114
+
115
+ if not tag:
116
+ tag = V_PREVIEW
117
+
118
+ log.info(f"Switching to {tag}")
119
+ if tag == V_PREVIEW:
120
+ git.switch_branch(repo=mpy_path, branch="master")
121
+ else:
122
+ if tag == "stable":
123
+ tag = get_stable_mp_version()
124
+ git.switch_tag(tag, repo=mpy_path)
125
+ result = match_lib_with_mpy(version_tag=tag, mpy_path=mpy_path, lib_path=mpy_lib_path)
126
+
127
+ log.info(f"{str(mpy_path):<40} {git.get_local_tag(mpy_path)}")
128
+ log.info(f"{str(mpy_lib_path):<40} {git.get_local_tag(mpy_lib_path)}")
129
+ try:
130
+ sub_mod_path = mpy_path / "lib/micropython-lib"
131
+ if (sub_mod_path / ".git").exists():
132
+ log.info(f"{str(sub_mod_path):<40} {git.get_local_tag(sub_mod_path)}")
133
+ except Exception:
134
+ pass
135
+ return result
136
+
137
+
138
+ def repo_paths(dest_path: Path) -> Tuple[Path, Path]:
139
+ """Return the paths to the micropython and micropython-lib repos, given a path to the repos.'"""
140
+ if not dest_path.exists():
141
+ os.mkdir(dest_path)
142
+ # repos are relative to provided path
143
+ if dest_path != CONFIG.repo_path:
144
+ mpy_path = dest_path / "micropython"
145
+ mpy_lib_path = dest_path / "micropython-lib"
146
+ else:
147
+ mpy_path = CONFIG.mpy_path
148
+ mpy_lib_path = CONFIG.mpy_lib_path
149
+
150
+ # if no repos then error
151
+ if not (mpy_path / ".git").exists():
152
+ log.error("micropython repo not found")
153
+ raise LookupError
154
+ if not (mpy_lib_path / ".git").exists():
155
+ log.error("micropython-lib repo not found")
156
+ raise LookupError
157
+ return mpy_path, mpy_lib_path