micropython-stubber 1.23.3__py3-none-any.whl → 1.24.1__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 (69) hide show
  1. {micropython_stubber-1.23.3.dist-info → micropython_stubber-1.24.1.dist-info}/METADATA +29 -11
  2. {micropython_stubber-1.23.3.dist-info → micropython_stubber-1.24.1.dist-info}/RECORD +68 -65
  3. {micropython_stubber-1.23.3.dist-info → micropython_stubber-1.24.1.dist-info}/WHEEL +1 -1
  4. mpflash/README.md +2 -2
  5. mpflash/mpflash/basicgit.py +22 -2
  6. mpflash/mpflash/common.py +23 -13
  7. mpflash/mpflash/downloaded.py +10 -2
  8. mpflash/mpflash/flash/esp.py +1 -1
  9. mpflash/mpflash/mpboard_id/__init__.py +9 -4
  10. mpflash/mpflash/mpboard_id/add_boards.py +25 -14
  11. mpflash/mpflash/mpboard_id/board.py +2 -2
  12. mpflash/mpflash/mpboard_id/board_id.py +10 -6
  13. mpflash/mpflash/mpboard_id/board_info.zip +0 -0
  14. mpflash/mpflash/mpremoteboard/__init__.py +13 -8
  15. mpflash/mpflash/vendor/board_database.py +185 -0
  16. mpflash/mpflash/vendor/readme.md +10 -1
  17. mpflash/mpflash/versions.py +28 -40
  18. mpflash/poetry.lock +1147 -231
  19. mpflash/pyproject.toml +4 -3
  20. stubber/__init__.py +1 -1
  21. stubber/board/createstubs.py +76 -34
  22. stubber/board/createstubs_db.py +34 -25
  23. stubber/board/createstubs_db_min.py +90 -83
  24. stubber/board/createstubs_db_mpy.mpy +0 -0
  25. stubber/board/createstubs_mem.py +34 -25
  26. stubber/board/createstubs_mem_min.py +123 -116
  27. stubber/board/createstubs_mem_mpy.mpy +0 -0
  28. stubber/board/createstubs_min.py +154 -145
  29. stubber/board/createstubs_mpy.mpy +0 -0
  30. stubber/board/modulelist.txt +16 -0
  31. stubber/codemod/enrich.py +301 -86
  32. stubber/codemod/merge_docstub.py +251 -66
  33. stubber/codemod/test_enrich.py +87 -0
  34. stubber/codemod/visitors/type_helpers.py +182 -0
  35. stubber/commands/build_cmd.py +16 -3
  36. stubber/commands/clone_cmd.py +3 -3
  37. stubber/commands/config_cmd.py +4 -2
  38. stubber/commands/enrich_folder_cmd.py +33 -21
  39. stubber/commands/get_core_cmd.py +1 -2
  40. stubber/commands/get_docstubs_cmd.py +60 -6
  41. stubber/commands/get_frozen_cmd.py +15 -12
  42. stubber/commands/get_mcu_cmd.py +3 -3
  43. stubber/commands/merge_cmd.py +1 -2
  44. stubber/commands/publish_cmd.py +19 -4
  45. stubber/commands/stub_cmd.py +3 -3
  46. stubber/commands/switch_cmd.py +3 -5
  47. stubber/commands/variants_cmd.py +3 -3
  48. stubber/cst_transformer.py +52 -17
  49. stubber/freeze/common.py +27 -11
  50. stubber/freeze/freeze_manifest_2.py +8 -1
  51. stubber/freeze/get_frozen.py +4 -1
  52. stubber/merge_config.py +111 -0
  53. stubber/minify.py +1 -2
  54. stubber/publish/database.py +51 -10
  55. stubber/publish/merge_docstubs.py +38 -17
  56. stubber/publish/package.py +32 -18
  57. stubber/publish/publish.py +8 -8
  58. stubber/publish/stubpackage.py +117 -50
  59. stubber/rst/lookup.py +205 -41
  60. stubber/rst/reader.py +106 -59
  61. stubber/rst/rst_utils.py +24 -11
  62. stubber/stubber.py +1 -1
  63. stubber/stubs_from_docs.py +31 -13
  64. stubber/update_module_list.py +2 -2
  65. stubber/utils/config.py +33 -13
  66. stubber/utils/post.py +9 -6
  67. stubber/publish/missing_class_methods.py +0 -51
  68. {micropython_stubber-1.23.3.dist-info → micropython_stubber-1.24.1.dist-info}/LICENSE +0 -0
  69. {micropython_stubber-1.23.3.dist-info → micropython_stubber-1.24.1.dist-info}/entry_points.txt +0 -0
@@ -23,9 +23,10 @@ from mpflash.versions import micropython_versions
23
23
  # and the #define MICROPY_HW_MCU_NAME "STM32F767xx"
24
24
  RE_H_MICROPY_HW_BOARD_NAME = re.compile(r"#define\s+MICROPY_HW_BOARD_NAME\s+\"(.+)\"")
25
25
  RE_H_MICROPY_HW_MCU_NAME = re.compile(r"#define\s+MICROPY_HW_MCU_NAME\s+\"(.+)\"")
26
- # find in the mpconfigboard.cmake files
27
-
28
- RE_CMAKE_MICROPY_HW_BOARD_NAME = re.compile(r"MICROPY_HW_BOARD_NAME\s?=\s?\"(?P<variant>[\w\s\S]*)\"")
26
+ # find boards and variants in the mpconfigboard*.cmake files
27
+ RE_CMAKE_MICROPY_HW_BOARD_NAME = re.compile(
28
+ r"MICROPY_HW_BOARD_NAME\s?=\s?\"(?P<variant>[\w\s\S]*)\""
29
+ )
29
30
  RE_CMAKE_MICROPY_HW_MCU_NAME = re.compile(r"MICROPY_HW_MCU_NAME\s?=\s?\"(?P<variant>[\w\s\S]*)\"")
30
31
  # TODO: normal make files
31
32
 
@@ -42,10 +43,8 @@ def boards_from_repo(mpy_path: Path, version: str, family: Optional[str] = None)
42
43
  """
43
44
  if not mpy_path.exists() or not mpy_path.is_dir():
44
45
  raise FileNotFoundError(f"MicroPython path {mpy_path} does not exist.")
45
- if not family:
46
- family = "micropython"
47
- if not version:
48
- version = git.get_local_tag() # type: ignore
46
+ family = family or "micropython"
47
+ version = version or git.get_local_tag() # type: ignore
49
48
  if not version:
50
49
  raise ValueError("No version provided and no local tag found.")
51
50
 
@@ -53,9 +52,10 @@ def boards_from_repo(mpy_path: Path, version: str, family: Optional[str] = None)
53
52
  # look in mpconfigboard.h files
54
53
  board_list = boards_from_cmake(mpy_path, version, family)
55
54
 
56
- # look for variants in the .cmake files
55
+ # look for boards in the .cmake files
57
56
  board_list.extend(boards_from_headers(mpy_path, version, family))
58
- # TODO:? look for variants in the Makefile files
57
+
58
+ # TODO:? look for variants in the board.json files
59
59
 
60
60
  return board_list
61
61
 
@@ -63,7 +63,7 @@ def boards_from_repo(mpy_path: Path, version: str, family: Optional[str] = None)
63
63
  def boards_from_cmake(mpy_path: Path, version: str, family: str):
64
64
  """Get boards from the mpconfigboard.cmake files to the board_list."""
65
65
  board_list = []
66
- for path in mpy_path.glob("ports/**/mpconfigboard.cmake"):
66
+ for path in mpy_path.glob("ports/**/mpconfigboard*.cmake"):
67
67
  board = path.parent.name
68
68
  port = path.parent.parent.parent.name
69
69
  with open(path, "r") as f:
@@ -118,7 +118,9 @@ def boards_from_headers(mpy_path: Path, version: str, family: str):
118
118
  mcu_name = match[1]
119
119
  found += 1
120
120
  if found == 2:
121
- description = f"{board_name} with {mcu_name}" if mcu_name != "-" else board_name
121
+ description = (
122
+ f"{board_name} with {mcu_name}" if mcu_name != "-" else board_name
123
+ )
122
124
  board_list.append(
123
125
  Board(
124
126
  board_id=board,
@@ -160,6 +162,8 @@ def boards_for_versions(versions: List[str], mpy_path: Path):
160
162
  List[Board]: The list of Board objects.
161
163
  """
162
164
  board_list: List[Board] = []
165
+ # first fetch all tags from the repository
166
+ git.fetch(mpy_path)
163
167
  for version in track(versions, description="Searching MicroPython versions"):
164
168
  if git.checkout_tag(tag=version, repo=mpy_path):
165
169
  new_ones = boards_from_repo(mpy_path, version, family="micropython")
@@ -197,9 +201,10 @@ def make_table(board_list: List[Board]) -> rich.table.Table:
197
201
  is_wide = True
198
202
 
199
203
  table = rich.table.Table(title="MicroPython Board Information")
204
+ table.add_column("Port", justify="left", style="magenta")
200
205
  table.add_column("BOARD_ID", justify="left", style="green")
206
+ table.add_column("Variant(s)", justify="left", style="blue")
201
207
  table.add_column("Description", justify="left", style="cyan")
202
- table.add_column("Port", justify="left", style="magenta")
203
208
  table.add_column("Board Name", justify="left", style="blue")
204
209
  if is_wide:
205
210
  table.add_column("MCU Name", justify="left", style="blue")
@@ -209,7 +214,7 @@ def make_table(board_list: List[Board]) -> rich.table.Table:
209
214
  table.add_column("Family", justify="left", style="blue")
210
215
 
211
216
  for board in board_list:
212
- row = [board.board_id, board.description, *(board.port, board.board_name)]
217
+ row = [board.port, board.board_id, board.variant, board.description, board.board_name]
213
218
  if is_wide:
214
219
  row.append(board.mcu_name)
215
220
  row.extend((str(Path(board.path).suffix), board.version))
@@ -222,7 +227,13 @@ def make_table(board_list: List[Board]) -> rich.table.Table:
222
227
 
223
228
  def ask_mpy_path():
224
229
  """Ask the user for the path to the MicroPython repository."""
225
- questions = [inquirer.Text("mpy_path", message="Enter the path to the MicroPython repository", default=".\\repos\\micropython")]
230
+ questions = [
231
+ inquirer.Text(
232
+ "mpy_path",
233
+ message="Enter the path to the MicroPython repository",
234
+ default=".\\repos\\micropython",
235
+ )
236
+ ]
226
237
  if answers := inquirer.prompt(questions):
227
238
  return Path(answers["mpy_path"])
228
239
  else:
@@ -1,6 +1,6 @@
1
1
  from dataclasses import dataclass, field
2
2
  from pathlib import Path
3
- from typing import Union
3
+ from typing import Union
4
4
 
5
5
 
6
6
  # - source : get_boardnames.py
@@ -20,7 +20,7 @@ class Board:
20
20
  family: str = field(default="micropython")
21
21
  mcu_name: str = field(default="")
22
22
  cpu: str = field(default="")
23
- # TODO: add variant
23
+ variant: str = field(default="")
24
24
 
25
25
  def __post_init__(self):
26
26
  if not self.cpu:
@@ -56,14 +56,12 @@ def _find_board_id_by_description(
56
56
  Path to the board_info.json file (optional)
57
57
 
58
58
  """
59
- # FIXME: functional overlap with
59
+ # Some functional overlap with
60
60
  # src\mpflash\mpflash\mpboard_id\__init__.py find_known_board
61
61
 
62
+ candidate_boards = read_known_boardinfo(board_info)
62
63
  if not short_descr and " with " in descr:
63
64
  short_descr = descr.split(" with ")[0]
64
-
65
- candidate_boards = read_known_boardinfo(board_info)
66
-
67
65
  if version:
68
66
  # filter for matching version
69
67
  if version in ("preview", "stable"):
@@ -71,16 +69,22 @@ def _find_board_id_by_description(
71
69
  version = get_stable_mp_version()
72
70
  known_versions = sorted({b.version for b in candidate_boards})
73
71
  if version not in known_versions:
74
- # FIXME if latest stable is newer than the last version in the boardlist this will fail
75
72
  log.trace(f"Version {version} not found in board info, using latest known version {known_versions[-1]}")
76
- version = known_versions[-1]
73
+ version = '.'.join(known_versions[-1].split('.')[:2]) # take only major.minor
77
74
  if version_matches := [b for b in candidate_boards if b.version.startswith(version)]:
78
75
  candidate_boards = version_matches
79
76
  else:
80
77
  raise MPFlashError(f"No board info found for version {version}")
78
+ # First try full match on description, then partial match
81
79
  matches = [b for b in candidate_boards if b.description == descr]
82
80
  if not matches and short_descr:
83
81
  matches = [b for b in candidate_boards if b.description == short_descr]
82
+ if not matches:
83
+ # partial match (for added VARIANT)
84
+ matches = [b for b in candidate_boards if b.description.startswith(descr)]
85
+ if not matches and short_descr:
86
+ matches = [b for b in candidate_boards if b.description.startswith(short_descr)]
84
87
  if not matches:
85
88
  raise MPFlashError(f"No board info found for description '{descr}' or '{short_descr}'")
86
89
  return sorted(matches, key=lambda x: x.version)
90
+
Binary file
@@ -55,7 +55,7 @@ class MPRemoteBoard:
55
55
  self.arch = ""
56
56
  self.mpy = ""
57
57
  self.build = ""
58
- self.location = location # USB location
58
+ self.location = location # USB location
59
59
  self.toml = {}
60
60
  if update:
61
61
  self.get_mcu_info()
@@ -97,7 +97,9 @@ class MPRemoteBoard:
97
97
 
98
98
  if sys.platform == "win32":
99
99
  # Windows sort of comports by number - but fallback to device name
100
- return sorted(output, key=lambda x: int(x.split()[0][3:]) if x.split()[0][3:].isdigit() else x)
100
+ return sorted(
101
+ output, key=lambda x: int(x.split()[0][3:]) if x.split()[0][3:].isdigit() else x
102
+ )
101
103
  # sort by device name
102
104
  return sorted(output)
103
105
 
@@ -116,9 +118,10 @@ class MPRemoteBoard:
116
118
  ["run", str(HERE / "mpy_fw_info.py")],
117
119
  no_info=True,
118
120
  timeout=timeout,
119
- resume=True, # Avoid restarts
121
+ resume=False, # Avoid restarts
120
122
  )
121
- if rc != OK:
123
+ if rc:
124
+ log.debug(f"rc: {rc}, result: {result}")
122
125
  raise ConnectionError(f"Failed to get mcu_info for {self.serialport}")
123
126
  # Ok we have the info, now parse it
124
127
  raw_info = result[0].strip()
@@ -134,7 +137,9 @@ class MPRemoteBoard:
134
137
  self.description = descr = info["board"]
135
138
  pos = descr.rfind(" with")
136
139
  short_descr = descr[:pos].strip() if pos != -1 else ""
137
- if board_name := find_board_id_by_description(descr, short_descr, version=self.version):
140
+ if board_name := find_board_id_by_description(
141
+ descr, short_descr, version=self.version
142
+ ):
138
143
  self.board = board_name
139
144
  else:
140
145
  self.board = "UNKNOWN_BOARD"
@@ -174,7 +179,7 @@ class MPRemoteBoard:
174
179
  except Exception as e:
175
180
  log.error(f"Failed to parse board_info.toml: {e}")
176
181
  else:
177
- log.trace(f"Failed to read board_info.toml: {result}")
182
+ log.trace(f"Did not find a board_info.toml: {result}")
178
183
 
179
184
  def disconnect(self) -> bool:
180
185
  """
@@ -202,7 +207,7 @@ class MPRemoteBoard:
202
207
  log_errors: bool = True,
203
208
  no_info: bool = False,
204
209
  timeout: int = 60,
205
- resume: bool = False,
210
+ resume: Optional[bool] = None,
206
211
  **kwargs,
207
212
  ):
208
213
  """
@@ -223,7 +228,7 @@ class MPRemoteBoard:
223
228
  if self.serialport:
224
229
  prefix += ["connect", self.serialport]
225
230
  # if connected add resume to keep state between commands
226
- if self.connected or resume:
231
+ if (resume != False) and self.connected or resume:
227
232
  prefix += ["resume"]
228
233
  cmd = prefix + cmd
229
234
  log.debug(" ".join(cmd))
@@ -0,0 +1,185 @@
1
+ """
2
+ The micropython git repo contains many 'board.json' files.
3
+
4
+ This is an example:
5
+ ports/stm32/boards/PYBV11/board.json
6
+
7
+ {
8
+ "deploy": [
9
+ "../PYBV10/deploy.md"
10
+ ],
11
+ "docs": "",
12
+ "features": [],
13
+ "images": [
14
+ "PYBv1_1.jpg",
15
+ "PYBv1_1-C.jpg",
16
+ "PYBv1_1-E.jpg"
17
+ ],
18
+ "mcu": "stm32f4",
19
+ "product": "Pyboard v1.1",
20
+ "thumbnail": "",
21
+ "url": "https://store.micropython.org/product/PYBv1.1",
22
+ "variants": {
23
+ "DP": "Double-precision float",
24
+ "DP_THREAD": "Double precision float + Threads",
25
+ "NETWORK": "Wiznet 5200 Driver",
26
+ "THREAD": "Threading"
27
+ },
28
+ "vendor": "George Robotics"
29
+ }
30
+
31
+ This module implements `class Database` which reads all 'board.json' files and
32
+ provides a way to browse it's data.
33
+ """
34
+
35
+ from __future__ import annotations
36
+
37
+ import json
38
+ from dataclasses import dataclass, field
39
+ from glob import glob
40
+ from pathlib import Path
41
+
42
+
43
+ @dataclass(order=True)
44
+ class Variant:
45
+ name: str
46
+ """
47
+ Example: "DP_THREAD"
48
+ """
49
+ text: str
50
+ """
51
+ Example: "Double precision float + Threads"
52
+ """
53
+ board: Board = field(repr=False)
54
+
55
+
56
+ @dataclass(order=True)
57
+ class Board:
58
+ name: str
59
+ """
60
+ Example: "PYBV11"
61
+ """
62
+ variants: list[Variant]
63
+ """
64
+ List of variants available for this board.
65
+ Variants are sorted. May be an empty list if no variants are available.
66
+ Example key: "DP_THREAD"
67
+ """
68
+ url: str
69
+ """
70
+ Primary URL to link to this board.
71
+ """
72
+ mcu: str
73
+ """
74
+ Example: "stm32f4"
75
+ """
76
+ product: str
77
+ """
78
+ Example: "Pyboard v1.1"
79
+ """
80
+ vendor: str
81
+ """
82
+ Example: "George Robotics"
83
+ """
84
+ images: list[str]
85
+ """
86
+ Images of this board, stored in the micropython-media repository.
87
+ Example: ["PYBv1_1.jpg", "PYBv1_1-C.jpg", "PYBv1_1-E.jpg"]
88
+ """
89
+ deploy: list[str]
90
+ """
91
+ Files that explain how to deploy for this board:
92
+ Example: ["../PYBV10/deploy.md"]
93
+ """
94
+ port: Port | None = field(default=None, compare=False)
95
+
96
+ @staticmethod
97
+ def factory(filename_json: Path) -> Board:
98
+ with filename_json.open() as f:
99
+ board_json = json.load(f)
100
+
101
+ board = Board(
102
+ name=filename_json.parent.name,
103
+ variants=[],
104
+ url=board_json["url"],
105
+ mcu=board_json["mcu"],
106
+ product=board_json["product"],
107
+ vendor=board_json["vendor"],
108
+ images=board_json["images"],
109
+ deploy=board_json["deploy"],
110
+ )
111
+ board.variants.extend(
112
+ sorted([Variant(*v, board) for v in board_json.get("variants", {}).items()]) # type: ignore
113
+ )
114
+ return board
115
+
116
+
117
+ @dataclass(order=True)
118
+ class Port:
119
+ name: str
120
+ """
121
+ Example: "stm32"
122
+ """
123
+ boards: dict[str, Board] = field(default_factory=dict, repr=False)
124
+ """
125
+ Example key: "PYBV11"
126
+ """
127
+
128
+
129
+ @dataclass
130
+ class Database:
131
+ """
132
+ This database contains all information retrieved from all 'board.json' files.
133
+ """
134
+
135
+ mpy_root_directory: Path = field(repr=False)
136
+ port_filter: str = field(default="", repr=False)
137
+
138
+ ports: dict[str, Port] = field(default_factory=dict)
139
+ boards: dict[str, Board] = field(default_factory=dict)
140
+
141
+ def __post_init__(self) -> None:
142
+ mpy_dir = self.mpy_root_directory
143
+ # Take care to avoid using Path.glob! Performance was 15x slower.
144
+ for p in glob(f"{mpy_dir}/ports/**/boards/**/board.json"):
145
+ filename_json = Path(p)
146
+ port_name = filename_json.parent.parent.parent.name
147
+ if self.port_filter and self.port_filter != port_name:
148
+ continue
149
+
150
+ # Create a port
151
+ port = self.ports.get(port_name, None)
152
+ if port is None:
153
+ port = Port(port_name)
154
+ self.ports[port_name] = port
155
+
156
+ # Load board.json and attach it to the board
157
+ board = Board.factory(filename_json)
158
+ board.port = port
159
+
160
+ port.boards[board.name] = board
161
+ self.boards[board.name] = board
162
+
163
+ # Add 'special' ports, that don't have boards
164
+ # TODO(mst) Tidy up later (variant descriptions etc)
165
+ for special_port_name in ["unix", "webassembly", "windows"]:
166
+ if self.port_filter and self.port_filter != special_port_name:
167
+ continue
168
+ path = Path(mpy_dir, "ports", special_port_name)
169
+ variant_names = [var.name for var in path.glob("variants/*") if var.is_dir()]
170
+ board = Board(
171
+ special_port_name,
172
+ [],
173
+ f"https://github.com/micropython/micropython/blob/master/ports/{special_port_name}/README.md",
174
+ "",
175
+ "",
176
+ "",
177
+ [],
178
+ [],
179
+ )
180
+ board.variants = [Variant(v, "", board) for v in variant_names]
181
+ port = Port(special_port_name, {special_port_name: board})
182
+ board.port = port
183
+
184
+ self.ports[special_port_name] = port
185
+ self.boards[board.name] = board
@@ -1,3 +1,12 @@
1
1
  These modules are vendored from the following repositories:
2
2
 
3
- micropython/micropython
3
+ - https://github.com/micropython/micropython (MIT)
4
+ - dfu.py
5
+ - pydfy.py
6
+
7
+ - https://github.com/mattytrentini/mpbuild (MIT)
8
+ - board_database.py
9
+
10
+ - https://github.com/click-contrib/click-aliases (Public Domain)
11
+ - click_aliases.py (Robbin Bonthond)
12
+
@@ -1,14 +1,12 @@
1
1
  """
2
- #############################################################
3
- # Version handling copied from stubber/utils/versions.py
4
- #############################################################
2
+ Version handling for mpflash and micropython-stubber
5
3
  """
6
4
 
7
5
  from pathlib import Path
8
6
 
9
7
  from cache_to_disk import NoCacheCondition, cache_to_disk
10
8
  from loguru import logger as log
11
- from packaging.version import parse
9
+ from packaging.version import Version, parse
12
10
 
13
11
  import mpflash.basicgit as git
14
12
  from mpflash.common import GH_CLIENT
@@ -71,58 +69,48 @@ def clean_version(
71
69
  return version
72
70
 
73
71
 
72
+ def is_version(version: str):
73
+ """Check if the version is a valid version string"""
74
+ return Version._regex.search(version) is not None
75
+
76
+
74
77
  @cache_to_disk(n_days_to_cache=1)
75
- def micropython_versions(minver: str = "v1.20", reverse: bool = False):
78
+ def micropython_versions(minver: str = "v1.20", reverse: bool = False, cache_it=True):
76
79
  """Get the list of micropython versions from github tags"""
77
- cache_it = True
80
+
78
81
  try:
79
82
  gh_client = GH_CLIENT
80
83
  repo = gh_client.get_repo("micropython/micropython")
81
- versions = [tag.name for tag in repo.get_tags() if parse(tag.name) >= parse(minver)]
84
+ tags = [tag.name for tag in repo.get_tags() if parse(tag.name) >= parse(minver)]
85
+ versions = [v for v in tags if not v.endswith(V_PREVIEW)]
82
86
  # Only keep the last preview
83
- versions = [v for v in versions if not v.endswith(V_PREVIEW) or v == versions[-1]]
84
- except Exception:
85
- versions = [
86
- "v9.99.9-preview",
87
- "v1.22.2",
88
- "v1.22.1",
89
- "v1.22.0",
90
- "v1.21.1",
91
- "v1.21.0",
92
- "v1.20.0",
93
- "v1.19.1",
94
- "v1.19",
95
- "v1.18",
96
- "v1.17",
97
- "v1.16",
98
- "v1.15",
99
- "v1.14",
100
- "v1.13",
101
- "v1.12",
102
- "v1.11",
103
- "v1.10",
104
- ]
105
- cache_it = False
106
- versions = [v for v in versions if parse(v) >= parse(minver)]
107
- # remove all but the most recent (preview) version
108
- versions = versions[:1] + [v for v in versions if "preview" not in v]
109
- versions = sorted(versions, reverse=reverse)
87
+ preview = sorted([v for v in tags if v.endswith(V_PREVIEW)], reverse=True)[0]
88
+ versions.append(preview)
89
+ except Exception as e:
90
+ log.error(e)
91
+ versions = []
92
+ # returns - but does not cache
93
+ raise NoCacheCondition(function_value=versions)
94
+ # remove any duplicates and sort
95
+ versions = sorted(list(set(versions)), reverse=reverse, key=lambda s: (not is_version(s), s))
110
96
  if cache_it:
111
97
  return versions
112
98
  # returns - but does not cache
113
99
  raise NoCacheCondition(function_value=versions)
114
100
 
115
101
 
116
- def get_stable_mp_version() -> str:
102
+ def get_stable_mp_version(cache_it=True) -> str:
117
103
  # read the versions from the git tags
118
- all_versions = micropython_versions(minver=OLDEST_VERSION)
119
- return [v for v in all_versions if not v.endswith(V_PREVIEW)][-1]
104
+ all_versions = micropython_versions(minver=OLDEST_VERSION, cache_it=cache_it)
105
+ versions = [v for v in all_versions if not v.endswith(V_PREVIEW)]
106
+ return versions[-1] if versions else ""
120
107
 
121
108
 
122
- def get_preview_mp_version() -> str:
109
+ def get_preview_mp_version(cache_it=True) -> str:
123
110
  # read the versions from the git tags
124
- all_versions = micropython_versions(minver=OLDEST_VERSION)
125
- return [v for v in all_versions if v.endswith(V_PREVIEW)][-1]
111
+ all_versions = micropython_versions(minver=OLDEST_VERSION, cache_it=cache_it)
112
+ versions = [v for v in all_versions if v.endswith(V_PREVIEW)]
113
+ return versions[0] if versions else ""
126
114
 
127
115
 
128
116
  # Do not cache , same path will have different versions checked out