micropython-stubber 1.24.1__py3-none-any.whl → 1.24.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. {micropython_stubber-1.24.1.dist-info → micropython_stubber-1.24.4.dist-info}/METADATA +9 -29
  2. micropython_stubber-1.24.4.dist-info/RECORD +107 -0
  3. {micropython_stubber-1.24.1.dist-info → micropython_stubber-1.24.4.dist-info}/WHEEL +1 -1
  4. stubber/__init__.py +1 -1
  5. stubber/board/createstubs.py +44 -38
  6. stubber/board/createstubs_db.py +17 -12
  7. stubber/board/createstubs_db_min.py +63 -63
  8. stubber/board/createstubs_db_mpy.mpy +0 -0
  9. stubber/board/createstubs_mem.py +17 -12
  10. stubber/board/createstubs_mem_min.py +99 -99
  11. stubber/board/createstubs_mem_mpy.mpy +0 -0
  12. stubber/board/createstubs_min.py +111 -112
  13. stubber/board/createstubs_mpy.mpy +0 -0
  14. stubber/board/modulelist.txt +27 -27
  15. stubber/codemod/board.py +1 -1
  16. stubber/codemod/enrich.py +13 -13
  17. stubber/codemod/merge_docstub.py +83 -53
  18. stubber/codemod/visitors/type_helpers.py +143 -41
  19. stubber/commands/enrich_folder_cmd.py +17 -17
  20. stubber/commands/get_docstubs_cmd.py +27 -9
  21. stubber/commands/get_frozen_cmd.py +1 -0
  22. stubber/commands/merge_cmd.py +2 -4
  23. stubber/merge_config.py +5 -36
  24. stubber/minify.py +3 -3
  25. stubber/modcat.py +118 -0
  26. stubber/publish/merge_docstubs.py +22 -5
  27. stubber/publish/stubpackage.py +33 -28
  28. stubber/rst/lookup.py +6 -23
  29. stubber/rst/reader.py +8 -13
  30. stubber/stubs_from_docs.py +2 -1
  31. stubber/tools/manifestfile.py +2 -1
  32. stubber/{cst_transformer.py → typing_collector.py} +36 -4
  33. micropython_stubber-1.24.1.dist-info/RECORD +0 -161
  34. mpflash/README.md +0 -220
  35. mpflash/libusb_flash.ipynb +0 -203
  36. mpflash/mpflash/__init__.py +0 -0
  37. mpflash/mpflash/add_firmware.py +0 -98
  38. mpflash/mpflash/ask_input.py +0 -236
  39. mpflash/mpflash/basicgit.py +0 -324
  40. mpflash/mpflash/bootloader/__init__.py +0 -2
  41. mpflash/mpflash/bootloader/activate.py +0 -60
  42. mpflash/mpflash/bootloader/detect.py +0 -82
  43. mpflash/mpflash/bootloader/manual.py +0 -101
  44. mpflash/mpflash/bootloader/micropython.py +0 -12
  45. mpflash/mpflash/bootloader/touch1200.py +0 -36
  46. mpflash/mpflash/cli_download.py +0 -129
  47. mpflash/mpflash/cli_flash.py +0 -224
  48. mpflash/mpflash/cli_group.py +0 -111
  49. mpflash/mpflash/cli_list.py +0 -87
  50. mpflash/mpflash/cli_main.py +0 -39
  51. mpflash/mpflash/common.py +0 -217
  52. mpflash/mpflash/config.py +0 -44
  53. mpflash/mpflash/connected.py +0 -96
  54. mpflash/mpflash/download.py +0 -364
  55. mpflash/mpflash/downloaded.py +0 -138
  56. mpflash/mpflash/errors.py +0 -9
  57. mpflash/mpflash/flash/__init__.py +0 -55
  58. mpflash/mpflash/flash/esp.py +0 -59
  59. mpflash/mpflash/flash/stm32.py +0 -19
  60. mpflash/mpflash/flash/stm32_dfu.py +0 -104
  61. mpflash/mpflash/flash/uf2/__init__.py +0 -88
  62. mpflash/mpflash/flash/uf2/boardid.py +0 -15
  63. mpflash/mpflash/flash/uf2/linux.py +0 -136
  64. mpflash/mpflash/flash/uf2/macos.py +0 -42
  65. mpflash/mpflash/flash/uf2/uf2disk.py +0 -12
  66. mpflash/mpflash/flash/uf2/windows.py +0 -43
  67. mpflash/mpflash/flash/worklist.py +0 -170
  68. mpflash/mpflash/list.py +0 -106
  69. mpflash/mpflash/logger.py +0 -41
  70. mpflash/mpflash/mpboard_id/__init__.py +0 -98
  71. mpflash/mpflash/mpboard_id/add_boards.py +0 -262
  72. mpflash/mpflash/mpboard_id/board.py +0 -37
  73. mpflash/mpflash/mpboard_id/board_id.py +0 -90
  74. mpflash/mpflash/mpboard_id/board_info.zip +0 -0
  75. mpflash/mpflash/mpboard_id/store.py +0 -48
  76. mpflash/mpflash/mpremoteboard/__init__.py +0 -271
  77. mpflash/mpflash/mpremoteboard/mpy_fw_info.py +0 -152
  78. mpflash/mpflash/mpremoteboard/runner.py +0 -140
  79. mpflash/mpflash/vendor/board_database.py +0 -185
  80. mpflash/mpflash/vendor/click_aliases.py +0 -91
  81. mpflash/mpflash/vendor/dfu.py +0 -165
  82. mpflash/mpflash/vendor/pydfu.py +0 -605
  83. mpflash/mpflash/vendor/readme.md +0 -12
  84. mpflash/mpflash/versions.py +0 -123
  85. mpflash/poetry.lock +0 -2603
  86. mpflash/pyproject.toml +0 -66
  87. mpflash/stm32_udev_rules.md +0 -63
  88. stubber/codemod/test_enrich.py +0 -87
  89. {micropython_stubber-1.24.1.dist-info → micropython_stubber-1.24.4.dist-info}/LICENSE +0 -0
  90. {micropython_stubber-1.24.1.dist-info → micropython_stubber-1.24.4.dist-info}/entry_points.txt +0 -0
mpflash/mpflash/list.py DELETED
@@ -1,106 +0,0 @@
1
- from typing import List
2
-
3
- from rich.progress import track
4
- from rich.table import Table
5
-
6
- from mpflash.config import config
7
- from mpflash.mpremoteboard import MPRemoteBoard
8
- from mpflash.versions import clean_version
9
-
10
- from .logger import console
11
-
12
-
13
- def show_mcus(
14
- conn_mcus: List[MPRemoteBoard],
15
- title: str = "Connected boards",
16
- refresh: bool = True,
17
- ):
18
- console.print(mcu_table(conn_mcus, title, refresh))
19
-
20
-
21
- def abbrv_family(family: str, is_wide: bool) -> str:
22
- if not is_wide:
23
- ABRV = {"micropython": "upy", "circuitpython": "cpy", "unknown": "?"}
24
- return ABRV.get(family, family[:4])
25
- return family
26
-
27
-
28
- def mcu_table(
29
- conn_mcus: List[MPRemoteBoard],
30
- title: str = "Connected boards",
31
- refresh: bool = True,
32
- ):
33
- """
34
- builds a rich table with the connected boards information
35
- The columns of the table are adjusted to the terminal width
36
- the columns are :
37
- Narrow Wide
38
- - Serial Yes Yes
39
- - Family abbrv. Yes
40
- - Port - yes
41
- - Board Yes Yes BOARD_ID and Description, and the description from board_info.toml
42
- - CPU - Yes
43
- - Version Yes Yes
44
- - Build * * only if any of the mcus have a build
45
- - Location - - only if --usb is given
46
- """
47
- # refresh if requested
48
- if refresh:
49
- for mcu in track(
50
- conn_mcus,
51
- description="Updating board info",
52
- transient=True,
53
- show_speed=False,
54
- refresh_per_second=1,
55
- ):
56
- try:
57
- mcu.get_mcu_info()
58
- except ConnectionError:
59
- continue
60
- table = Table(
61
- title=title,
62
- title_style="magenta",
63
- header_style="bold magenta",
64
- collapse_padding=True,
65
- padding=(0, 0),
66
- )
67
- # Build the table
68
- # check if the terminal is wide enough to show all columns or if we need to collapse some
69
- is_wide = console.width > 99
70
- needs_build = any(mcu.build for mcu in conn_mcus)
71
-
72
- table.add_column("Serial" if is_wide else "Ser.", overflow="fold")
73
- table.add_column("Family" if is_wide else "Fam.", overflow="crop", max_width=None if is_wide else 4)
74
- if is_wide:
75
- table.add_column("Port")
76
- table.add_column("Board", overflow="fold")
77
- # table.add_column("Variant") # TODO: add variant
78
- if is_wide:
79
- table.add_column("CPU")
80
- table.add_column("Version", overflow="fold", min_width=5, max_width=16)
81
- if needs_build:
82
- table.add_column("Build" if is_wide else "Bld", justify="right")
83
- if config.usb:
84
- table.add_column("Location", overflow="fold", max_width=60)
85
- # fill the table with the data
86
- for mcu in conn_mcus:
87
- description = f"[italic bright_cyan]{mcu.description}" if mcu.description else ""
88
- if "description" in mcu.toml:
89
- description += f"\n[italic bright_green]{mcu.toml['description']}"
90
- row = [
91
- mcu.serialport if is_wide else mcu.serialport.replace("/dev/tty", "tty"),
92
- abbrv_family(mcu.family, is_wide),
93
- ]
94
- if is_wide:
95
- row.append(mcu.port)
96
- row.append(f"{mcu.board}\n{description}".strip())
97
- if is_wide:
98
- row.append(mcu.cpu)
99
- row.append(clean_version(mcu.version))
100
- if needs_build:
101
- row.append(mcu.build)
102
- if config.usb:
103
- row.append(mcu.location)
104
-
105
- table.add_row(*row)
106
- return table
mpflash/mpflash/logger.py DELETED
@@ -1,41 +0,0 @@
1
- """Logging."""
2
-
3
- from loguru import logger as log
4
- from rich.console import Console
5
-
6
- from .config import config
7
-
8
- console = Console()
9
-
10
-
11
- def _log_formatter(record: dict) -> str:
12
- """Log message formatter to combine loguru and rich formatting."""
13
- color_map = {
14
- "TRACE": "dim blue",
15
- "DEBUG": "cyan",
16
- "INFO": "bold",
17
- "SUCCESS": "bold green",
18
- "WARNING": "yellow",
19
- "ERROR": "bold red",
20
- "CRITICAL": "bold white on red",
21
- }
22
- lvl_color = color_map.get(record["level"].name, "cyan")
23
- return (
24
- "[not bold green]{time:HH:mm:ss}[/not bold green] | {level.icon} " + f"[{lvl_color}]{{message}}[/{lvl_color}]"
25
- )
26
-
27
-
28
- def set_loglevel(loglevel: str):
29
- """Set the log level for the logger"""
30
- try:
31
- log.remove()
32
- except ValueError:
33
- pass
34
- log.add(console.print, level=loglevel.upper(), colorize=False, format=_log_formatter) # type: ignore
35
-
36
-
37
- def make_quiet():
38
- """Make the logger quiet"""
39
- config.quiet = True
40
- console.quiet = True
41
- set_loglevel("CRITICAL")
@@ -1,98 +0,0 @@
1
- """
2
- Access to the micropython port and board information that is stored in the board_info.json file
3
- that is included in the module.
4
-
5
- """
6
-
7
- from functools import lru_cache
8
- from typing import List, Optional, Tuple
9
-
10
- from mpflash.errors import MPFlashError
11
- from mpflash.mpboard_id.board import Board
12
- from mpflash.mpboard_id.store import read_known_boardinfo
13
- from mpflash.versions import clean_version
14
-
15
- # KNOWN ports and boards are sourced from the micropython repo,
16
- # this info is stored in the board_info.json file
17
-
18
-
19
- def get_known_ports() -> List[str]:
20
- # TODO: Filter for Version
21
- mp_boards = read_known_boardinfo()
22
- # select the unique ports from info
23
- ports = set({board.port for board in mp_boards if board.port})
24
- return sorted(list(ports))
25
-
26
-
27
- def get_known_boards_for_port(
28
- port: Optional[str] = "", versions: Optional[List[str]] = None
29
- ) -> List[Board]:
30
- """
31
- Returns a list of boards for the given port and version(s)
32
-
33
- port: The Micropython port to filter for
34
- versions: Optional, The Micropython versions to filter for (actual versions required)
35
- """
36
- mp_boards = read_known_boardinfo()
37
- if versions:
38
- preview_or_stable = "preview" in versions or "stable" in versions
39
- else:
40
- preview_or_stable = False
41
-
42
- # filter for 'preview' as they are not in the board_info.json
43
- # instead use stable version
44
- versions = versions or []
45
- if "preview" in versions:
46
- versions.remove("preview")
47
- versions.append("stable")
48
- if versions:
49
- # make sure of the v prefix
50
- versions = [clean_version(v) for v in versions]
51
- # filter for the version(s)
52
- mp_boards = [board for board in mp_boards if board.version in versions]
53
- if not mp_boards and preview_or_stable:
54
- # nothing found - perhaps there is a newer version for which we do not have the board info yet
55
- # use the latest known version from the board info
56
- mp_boards = read_known_boardinfo()
57
- last_known_version = sorted({b.version for b in mp_boards})[-1]
58
- mp_boards = [board for board in mp_boards if board.version == last_known_version]
59
-
60
- # filter for the port
61
- if port:
62
- mp_boards = [board for board in mp_boards if board.port == port]
63
- return mp_boards
64
-
65
-
66
- def known_stored_boards(port: str, versions: Optional[List[str]] = None) -> List[Tuple[str, str]]:
67
- """
68
- Returns a list of tuples with the description and board name for the given port and version
69
-
70
- port : str : The Micropython port to filter for
71
- versions : List[str] : The Micropython versions to filter for (actual versions required)
72
- """
73
- mp_boards = get_known_boards_for_port(port, versions)
74
-
75
- boards = set({(f"{board.version} {board.description}", board.board_id) for board in mp_boards})
76
- return sorted(list(boards))
77
-
78
-
79
- @lru_cache(maxsize=20)
80
- def find_known_board(board_id: str) -> Board:
81
- """Find the board for the given BOARD_ID or 'board description' and return the board info as a Board object"""
82
- # Some functional overlap with:
83
- # mpboard_id\board_id.py _find_board_id_by_description
84
- info = read_known_boardinfo()
85
- for board_info in info:
86
- if board_id in (
87
- board_info.board_id,
88
- board_info.description,
89
- ) or board_info.description.startswith(board_id):
90
- if not board_info.cpu:
91
- # failsafe for older board_info.json files
92
- print(f"Board {board_id} has no CPU info, using port as CPU")
93
- if " with " in board_info.description:
94
- board_info.cpu = board_info.description.split(" with ")[-1]
95
- else:
96
- board_info.cpu = board_info.port
97
- return board_info
98
- raise MPFlashError(f"Board {board_id} not found")
@@ -1,262 +0,0 @@
1
- """
2
- Collects board name and description information from MicroPython and writes it to JSON and CSV files.
3
- """
4
-
5
- import re
6
- from pathlib import Path
7
- from typing import List, Optional
8
-
9
- import inquirer
10
- import rich
11
- import rich.table
12
- from rich.console import Console
13
- from rich.progress import track
14
-
15
- import mpflash.basicgit as git
16
- from mpflash.logger import log
17
- from mpflash.mpboard_id import Board
18
- from mpflash.mpboard_id.store import write_boardinfo_json
19
- from mpflash.versions import micropython_versions
20
-
21
- # look for all mpconfigboard.h files and extract the board name
22
- # from the #define MICROPY_HW_BOARD_NAME "PYBD_SF6"
23
- # and the #define MICROPY_HW_MCU_NAME "STM32F767xx"
24
- RE_H_MICROPY_HW_BOARD_NAME = re.compile(r"#define\s+MICROPY_HW_BOARD_NAME\s+\"(.+)\"")
25
- RE_H_MICROPY_HW_MCU_NAME = re.compile(r"#define\s+MICROPY_HW_MCU_NAME\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
- )
30
- RE_CMAKE_MICROPY_HW_MCU_NAME = re.compile(r"MICROPY_HW_MCU_NAME\s?=\s?\"(?P<variant>[\w\s\S]*)\"")
31
- # TODO: normal make files
32
-
33
-
34
- def boards_from_repo(mpy_path: Path, version: str, family: Optional[str] = None) -> List[Board]:
35
- """Collects board name and decriptions from mpconfigboard.h files.
36
-
37
- Args:
38
- mpy_path (Path): The path to the MicroPython repository.
39
- version (str): The version of MicroPython.
40
-
41
- Returns:
42
- List[Board]: A list of Board objects containing the board information.
43
- """
44
- if not mpy_path.exists() or not mpy_path.is_dir():
45
- raise FileNotFoundError(f"MicroPython path {mpy_path} does not exist.")
46
- family = family or "micropython"
47
- version = version or git.get_local_tag() # type: ignore
48
- if not version:
49
- raise ValueError("No version provided and no local tag found.")
50
-
51
- board_list: List[Board] = []
52
- # look in mpconfigboard.h files
53
- board_list = boards_from_cmake(mpy_path, version, family)
54
-
55
- # look for boards in the .cmake files
56
- board_list.extend(boards_from_headers(mpy_path, version, family))
57
-
58
- # TODO:? look for variants in the board.json files
59
-
60
- return board_list
61
-
62
-
63
- def boards_from_cmake(mpy_path: Path, version: str, family: str):
64
- """Get boards from the mpconfigboard.cmake files to the board_list."""
65
- board_list = []
66
- for path in mpy_path.glob("ports/**/mpconfigboard*.cmake"):
67
- board = path.parent.name
68
- port = path.parent.parent.parent.name
69
- with open(path, "r") as f:
70
- board_name = mcu_name = "-"
71
- for line in f:
72
- line = line.strip()
73
- if match := RE_CMAKE_MICROPY_HW_BOARD_NAME.match(line):
74
- description = match["variant"]
75
- board_list.append(
76
- Board(
77
- board_id=board,
78
- port=port,
79
- board_name=board_name,
80
- mcu_name=mcu_name,
81
- description=description,
82
- path=path.relative_to(mpy_path),
83
- version=version,
84
- family=family,
85
- )
86
- )
87
- elif match := RE_CMAKE_MICROPY_HW_MCU_NAME.match(line):
88
- description = match["variant"]
89
- board_list.append(
90
- Board(
91
- board_id=board,
92
- port=port,
93
- board_name=board_name,
94
- mcu_name=mcu_name,
95
- description=description,
96
- path=path.relative_to(mpy_path),
97
- version=version,
98
- family=family,
99
- )
100
- )
101
- return board_list
102
-
103
-
104
- def boards_from_headers(mpy_path: Path, version: str, family: str):
105
- """Get boards from the mpconfigboard.h files to the board_list."""
106
- board_list = []
107
- for path in mpy_path.glob("ports/**/mpconfigboard.h"):
108
- board = path.parent.name
109
- port = path.parent.parent.parent.name
110
- with open(path, "r") as f:
111
- board_name = mcu_name = "-"
112
- found = 0
113
- for line in f:
114
- if match := RE_H_MICROPY_HW_BOARD_NAME.match(line):
115
- board_name = match[1]
116
- found += 1
117
- elif match := RE_H_MICROPY_HW_MCU_NAME.match(line):
118
- mcu_name = match[1]
119
- found += 1
120
- if found == 2:
121
- description = (
122
- f"{board_name} with {mcu_name}" if mcu_name != "-" else board_name
123
- )
124
- board_list.append(
125
- Board(
126
- board_id=board,
127
- port=port,
128
- board_name=board_name,
129
- mcu_name=mcu_name,
130
- description=description,
131
- path=path.relative_to(mpy_path),
132
- version=version,
133
- family=family,
134
- )
135
- )
136
- found = 0
137
- if found == 1:
138
- description = board_name
139
- board_list.append(
140
- Board(
141
- board_id=board,
142
- port=port,
143
- board_name=board_name,
144
- mcu_name=mcu_name,
145
- description=description,
146
- path=path.relative_to(mpy_path),
147
- version=version,
148
- family=family,
149
- )
150
- )
151
- return board_list
152
-
153
-
154
- def boards_for_versions(versions: List[str], mpy_path: Path):
155
- """Gets the list of boards for multiple versions of MicroPython.
156
-
157
- Args:
158
- versions (List[str]): The list of MicroPython versions.
159
- mpy_path (Path): The path to the MicroPython repository.
160
-
161
- Returns:
162
- List[Board]: The list of Board objects.
163
- """
164
- board_list: List[Board] = []
165
- # first fetch all tags from the repository
166
- git.fetch(mpy_path)
167
- for version in track(versions, description="Searching MicroPython versions"):
168
- if git.checkout_tag(tag=version, repo=mpy_path):
169
- new_ones = boards_from_repo(mpy_path, version, family="micropython")
170
- print(f"Found {len(new_ones)} board definitions for {version}.")
171
- board_list += new_ones
172
- else:
173
- print(f"Could not checkout version {version}.")
174
-
175
- # sort the board_list by description and board
176
- print("Total number of boards found:", len(board_list))
177
-
178
- board_list = unique_boards(board_list)
179
- print("Unique board descriptions found:", len(board_list))
180
- return board_list
181
-
182
-
183
- def unique_boards(board_list: List[Board], *, key_version: bool = True):
184
- """Remove duplicate boards by 'BOARD_ID description' from the list."""
185
- seen = set()
186
- result = []
187
- for x in board_list:
188
- if key_version:
189
- key = f"{x.board_id}|{x.version}|{x.description}"
190
- else:
191
- key = f"{x.board_id}|{x.description}"
192
- if key not in seen:
193
- result.append(x)
194
- seen.add(key)
195
- result.sort(key=lambda x: x.description.lower())
196
- return result
197
-
198
-
199
- def make_table(board_list: List[Board]) -> rich.table.Table:
200
- """Creates a rich table with board information."""
201
- is_wide = True
202
-
203
- table = rich.table.Table(title="MicroPython Board Information")
204
- table.add_column("Port", justify="left", style="magenta")
205
- table.add_column("BOARD_ID", justify="left", style="green")
206
- table.add_column("Variant(s)", justify="left", style="blue")
207
- table.add_column("Description", justify="left", style="cyan")
208
- table.add_column("Board Name", justify="left", style="blue")
209
- if is_wide:
210
- table.add_column("MCU Name", justify="left", style="blue")
211
- table.add_column("Detection", justify="left", style="yellow")
212
- table.add_column("Version", justify="left", style="blue")
213
- if is_wide:
214
- table.add_column("Family", justify="left", style="blue")
215
-
216
- for board in board_list:
217
- row = [board.port, board.board_id, board.variant, board.description, board.board_name]
218
- if is_wide:
219
- row.append(board.mcu_name)
220
- row.extend((str(Path(board.path).suffix), board.version))
221
- if is_wide:
222
- row.append(board.family)
223
- table.add_row(*row)
224
-
225
- return table
226
-
227
-
228
- def ask_mpy_path():
229
- """Ask the user for the path to the MicroPython repository."""
230
- questions = [
231
- inquirer.Text(
232
- "mpy_path",
233
- message="Enter the path to the MicroPython repository",
234
- default=".\\repos\\micropython",
235
- )
236
- ]
237
- if answers := inquirer.prompt(questions):
238
- return Path(answers["mpy_path"])
239
- else:
240
- raise ValueError("No path provided.")
241
-
242
-
243
- def main():
244
- """Main function to collect and write board information."""
245
-
246
- console = Console()
247
-
248
- mpy_path = ask_mpy_path()
249
- versions = micropython_versions(minver="v1.10") + ["master"]
250
- board_list = boards_for_versions(versions, mpy_path)
251
-
252
- here = Path(__file__).parent
253
- log.info(write_boardinfo_json(board_list, folder=here))
254
- # write_files(board_list, folder=CONFIG.board_path)
255
-
256
- # table of when the board was added
257
- table = make_table(unique_boards(board_list, key_version=False))
258
- console.print(table)
259
-
260
-
261
- if __name__ == "__main__":
262
- main()
@@ -1,37 +0,0 @@
1
- from dataclasses import dataclass, field
2
- from pathlib import Path
3
- from typing import Union
4
-
5
-
6
- # - source : get_boardnames.py
7
- @dataclass
8
- class Board:
9
- """
10
- MicroPython Board definitions, parsed from the make and header files
11
- """
12
-
13
- port: str # micropython port
14
- board_id: str # BOARD_ID (Foldername) as used in the make files
15
- board_name: str # Short board description
16
- description: str # Long board description
17
- path: Union[Path, str]
18
- version: str = field(default="") # version of MicroPython""
19
- # versions: List[str] = field(default=[]) # version of MicroPython""
20
- family: str = field(default="micropython")
21
- mcu_name: str = field(default="")
22
- cpu: str = field(default="")
23
- variant: str = field(default="")
24
-
25
- def __post_init__(self):
26
- if not self.cpu:
27
- if " with " in self.description:
28
- self.cpu = self.description.split(" with ")[-1]
29
- else:
30
- self.cpu = self.port
31
-
32
- @staticmethod
33
- def from_dict(data: dict) -> "Board":
34
- return Board(**data)
35
-
36
- def to_dict(self) -> dict:
37
- return self.__dict__
@@ -1,90 +0,0 @@
1
- """
2
- Translate board description to board designator
3
- """
4
-
5
- import functools
6
- from pathlib import Path
7
- from typing import Optional
8
-
9
- from mpflash.errors import MPFlashError
10
- from mpflash.logger import log
11
- from mpflash.mpboard_id.store import read_known_boardinfo
12
- from mpflash.versions import clean_version, get_stable_mp_version
13
-
14
-
15
- def find_board_id_by_description(
16
- descr: str,
17
- short_descr: str,
18
- *,
19
- version: str,
20
- board_info: Optional[Path] = None,
21
- ) -> Optional[str]:
22
- """Find the MicroPython BOARD_ID based on the description in the firmware"""
23
-
24
- try:
25
- boards = _find_board_id_by_description(
26
- descr=descr,
27
- short_descr=short_descr,
28
- board_info=board_info,
29
- version=clean_version(version) if version else None,
30
- )
31
- return boards[-1].board_id
32
- except MPFlashError:
33
- return "UNKNOWN_BOARD"
34
-
35
-
36
- @functools.lru_cache(maxsize=20)
37
- def _find_board_id_by_description(
38
- *,
39
- descr: str,
40
- short_descr: str,
41
- version: Optional[str] = None,
42
- board_info: Optional[Path] = None,
43
- ):
44
- """
45
- Find the MicroPython BOARD_ID based on the description in the firmware
46
- using the pre-built board_info.json file
47
-
48
- Parameters:
49
- descr: str
50
- Description of the board
51
- short_descr: str
52
- Short description of the board (optional)
53
- version: str
54
- Version of the MicroPython firmware
55
- board_info: Path
56
- Path to the board_info.json file (optional)
57
-
58
- """
59
- # Some functional overlap with
60
- # src\mpflash\mpflash\mpboard_id\__init__.py find_known_board
61
-
62
- candidate_boards = read_known_boardinfo(board_info)
63
- if not short_descr and " with " in descr:
64
- short_descr = descr.split(" with ")[0]
65
- if version:
66
- # filter for matching version
67
- if version in ("preview", "stable"):
68
- # match last stable
69
- version = get_stable_mp_version()
70
- known_versions = sorted({b.version for b in candidate_boards})
71
- if version not in known_versions:
72
- log.trace(f"Version {version} not found in board info, using latest known version {known_versions[-1]}")
73
- version = '.'.join(known_versions[-1].split('.')[:2]) # take only major.minor
74
- if version_matches := [b for b in candidate_boards if b.version.startswith(version)]:
75
- candidate_boards = version_matches
76
- else:
77
- raise MPFlashError(f"No board info found for version {version}")
78
- # First try full match on description, then partial match
79
- matches = [b for b in candidate_boards if b.description == descr]
80
- if not matches and short_descr:
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)]
87
- if not matches:
88
- raise MPFlashError(f"No board info found for description '{descr}' or '{short_descr}'")
89
- return sorted(matches, key=lambda x: x.version)
90
-
Binary file
@@ -1,48 +0,0 @@
1
- import functools
2
- import zipfile
3
- from pathlib import Path
4
- from typing import Final, List, Optional
5
-
6
- import jsons
7
-
8
- from mpflash.mpboard_id.board import Board
9
-
10
- ###############################################################################################
11
- HERE: Final = Path(__file__).parent
12
- ###############################################################################################
13
-
14
-
15
- def write_boardinfo_json(board_list: List[Board], *, folder: Optional[Path] = None):
16
- """Writes the board information to a JSON file.
17
-
18
- Args:
19
- board_list (List[Board]): The list of Board objects.
20
- folder (Path): The folder where the compressed JSON file will be saved.
21
- """
22
- import zipfile
23
-
24
- if not folder:
25
- folder = HERE
26
- # create a zip file with the json file
27
- with zipfile.ZipFile(folder / "board_info.zip", "w", compression=zipfile.ZIP_DEFLATED) as zipf:
28
- # write the list to json file inside the zip
29
- with zipf.open("board_info.json", "w") as fp:
30
- fp.write(jsons.dumps(board_list, jdkwargs={"indent": 4}).encode())
31
-
32
-
33
- @functools.lru_cache(maxsize=20)
34
- def read_known_boardinfo(board_info: Optional[Path] = None) -> List[Board]:
35
- """Reads the board information from a JSON file in a zip file."""
36
-
37
- import zipfile
38
-
39
- if not board_info:
40
- board_info = HERE / "board_info.zip"
41
- if not board_info.exists():
42
- raise FileNotFoundError(f"Board info file not found: {board_info}")
43
-
44
- with zipfile.ZipFile(board_info, "r") as zf:
45
- with zf.open("board_info.json", "r") as file:
46
- info = jsons.loads(file.read().decode(encoding="utf-8"), List[Board])
47
-
48
- return info