micropython-stubber 1.23.1__py3-none-any.whl → 1.23.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (153) hide show
  1. {micropython_stubber-1.23.1.dist-info → micropython_stubber-1.23.2.dist-info}/LICENSE +30 -30
  2. {micropython_stubber-1.23.1.dist-info → micropython_stubber-1.23.2.dist-info}/METADATA +32 -15
  3. micropython_stubber-1.23.2.dist-info/RECORD +158 -0
  4. micropython_stubber-1.23.2.dist-info/entry_points.txt +5 -0
  5. mpflash/README.md +220 -194
  6. mpflash/libusb_flash.ipynb +203 -203
  7. mpflash/mpflash/add_firmware.py +98 -98
  8. mpflash/mpflash/ask_input.py +236 -236
  9. mpflash/mpflash/basicgit.py +284 -284
  10. mpflash/mpflash/bootloader/__init__.py +2 -2
  11. mpflash/mpflash/bootloader/activate.py +60 -60
  12. mpflash/mpflash/bootloader/detect.py +82 -82
  13. mpflash/mpflash/bootloader/manual.py +101 -101
  14. mpflash/mpflash/bootloader/micropython.py +12 -12
  15. mpflash/mpflash/bootloader/touch1200.py +36 -36
  16. mpflash/mpflash/cli_download.py +129 -129
  17. mpflash/mpflash/cli_flash.py +224 -219
  18. mpflash/mpflash/cli_group.py +111 -111
  19. mpflash/mpflash/cli_list.py +87 -81
  20. mpflash/mpflash/cli_main.py +39 -39
  21. mpflash/mpflash/common.py +210 -165
  22. mpflash/mpflash/config.py +44 -44
  23. mpflash/mpflash/connected.py +96 -78
  24. mpflash/mpflash/download.py +364 -364
  25. mpflash/mpflash/downloaded.py +130 -130
  26. mpflash/mpflash/errors.py +9 -9
  27. mpflash/mpflash/flash/__init__.py +55 -55
  28. mpflash/mpflash/flash/esp.py +59 -59
  29. mpflash/mpflash/flash/stm32.py +19 -19
  30. mpflash/mpflash/flash/stm32_dfu.py +104 -104
  31. mpflash/mpflash/flash/uf2/__init__.py +88 -88
  32. mpflash/mpflash/flash/uf2/boardid.py +15 -15
  33. mpflash/mpflash/flash/uf2/linux.py +136 -130
  34. mpflash/mpflash/flash/uf2/macos.py +42 -42
  35. mpflash/mpflash/flash/uf2/uf2disk.py +12 -12
  36. mpflash/mpflash/flash/uf2/windows.py +43 -43
  37. mpflash/mpflash/flash/worklist.py +170 -170
  38. mpflash/mpflash/list.py +106 -99
  39. mpflash/mpflash/logger.py +41 -41
  40. mpflash/mpflash/mpboard_id/__init__.py +93 -93
  41. mpflash/mpflash/mpboard_id/add_boards.py +251 -251
  42. mpflash/mpflash/mpboard_id/board.py +37 -37
  43. mpflash/mpflash/mpboard_id/board_id.py +86 -86
  44. mpflash/mpflash/mpboard_id/store.py +43 -43
  45. mpflash/mpflash/mpremoteboard/__init__.py +266 -222
  46. mpflash/mpflash/mpremoteboard/mpy_fw_info.py +141 -141
  47. mpflash/mpflash/mpremoteboard/runner.py +140 -140
  48. mpflash/mpflash/vendor/click_aliases.py +91 -91
  49. mpflash/mpflash/vendor/dfu.py +165 -165
  50. mpflash/mpflash/vendor/pydfu.py +605 -605
  51. mpflash/mpflash/vendor/readme.md +2 -2
  52. mpflash/mpflash/versions.py +135 -135
  53. mpflash/poetry.lock +1599 -1599
  54. mpflash/pyproject.toml +65 -65
  55. mpflash/stm32_udev_rules.md +62 -62
  56. stubber/__init__.py +3 -3
  57. stubber/board/board_info.csv +193 -193
  58. stubber/board/boot.py +34 -34
  59. stubber/board/createstubs.py +1004 -986
  60. stubber/board/createstubs_db.py +826 -825
  61. stubber/board/createstubs_db_min.py +332 -331
  62. stubber/board/createstubs_db_mpy.mpy +0 -0
  63. stubber/board/createstubs_lvgl.py +741 -741
  64. stubber/board/createstubs_lvgl_min.py +741 -741
  65. stubber/board/createstubs_mem.py +767 -766
  66. stubber/board/createstubs_mem_min.py +307 -306
  67. stubber/board/createstubs_mem_mpy.mpy +0 -0
  68. stubber/board/createstubs_min.py +295 -294
  69. stubber/board/createstubs_mpy.mpy +0 -0
  70. stubber/board/fw_info.py +141 -141
  71. stubber/board/info.py +183 -183
  72. stubber/board/main.py +19 -19
  73. stubber/board/modulelist.txt +247 -247
  74. stubber/board/pyrightconfig.json +34 -34
  75. stubber/bulk/mcu_stubber.py +437 -454
  76. stubber/codemod/_partials/__init__.py +48 -48
  77. stubber/codemod/_partials/db_main.py +147 -147
  78. stubber/codemod/_partials/lvgl_main.py +77 -77
  79. stubber/codemod/_partials/modules_reader.py +80 -80
  80. stubber/codemod/add_comment.py +53 -53
  81. stubber/codemod/add_method.py +65 -65
  82. stubber/codemod/board.py +317 -317
  83. stubber/codemod/enrich.py +151 -145
  84. stubber/codemod/merge_docstub.py +284 -284
  85. stubber/codemod/modify_list.py +54 -54
  86. stubber/codemod/utils.py +56 -56
  87. stubber/commands/build_cmd.py +94 -94
  88. stubber/commands/cli.py +49 -55
  89. stubber/commands/clone_cmd.py +78 -78
  90. stubber/commands/config_cmd.py +29 -29
  91. stubber/commands/enrich_folder_cmd.py +71 -71
  92. stubber/commands/get_core_cmd.py +71 -71
  93. stubber/commands/get_docstubs_cmd.py +92 -89
  94. stubber/commands/get_frozen_cmd.py +117 -114
  95. stubber/commands/get_mcu_cmd.py +102 -61
  96. stubber/commands/merge_cmd.py +66 -66
  97. stubber/commands/publish_cmd.py +118 -118
  98. stubber/commands/stub_cmd.py +31 -31
  99. stubber/commands/switch_cmd.py +62 -62
  100. stubber/commands/variants_cmd.py +48 -48
  101. stubber/cst_transformer.py +178 -178
  102. stubber/data/board_info.csv +193 -193
  103. stubber/data/board_info.json +1729 -1729
  104. stubber/data/micropython_tags.csv +15 -15
  105. stubber/data/requirements-core-micropython.txt +38 -38
  106. stubber/data/requirements-core-pycopy.txt +39 -39
  107. stubber/downloader.py +37 -36
  108. stubber/freeze/common.py +72 -68
  109. stubber/freeze/freeze_folder.py +69 -69
  110. stubber/freeze/freeze_manifest_2.py +126 -113
  111. stubber/freeze/get_frozen.py +131 -127
  112. stubber/get_cpython.py +112 -101
  113. stubber/get_lobo.py +59 -59
  114. stubber/minify.py +423 -419
  115. stubber/publish/bump.py +86 -86
  116. stubber/publish/candidates.py +275 -256
  117. stubber/publish/database.py +18 -18
  118. stubber/publish/defaults.py +40 -40
  119. stubber/publish/enums.py +24 -24
  120. stubber/publish/helpers.py +29 -29
  121. stubber/publish/merge_docstubs.py +136 -130
  122. stubber/publish/missing_class_methods.py +51 -49
  123. stubber/publish/package.py +150 -146
  124. stubber/publish/pathnames.py +51 -51
  125. stubber/publish/publish.py +120 -120
  126. stubber/publish/pypi.py +42 -38
  127. stubber/publish/stubpackage.py +1055 -1027
  128. stubber/rst/__init__.py +9 -9
  129. stubber/rst/classsort.py +78 -77
  130. stubber/rst/lookup.py +533 -530
  131. stubber/rst/output_dict.py +401 -401
  132. stubber/rst/reader.py +814 -814
  133. stubber/rst/report_return.py +77 -69
  134. stubber/rst/rst_utils.py +541 -540
  135. stubber/stubber.py +38 -38
  136. stubber/stubs_from_docs.py +90 -90
  137. stubber/tools/manifestfile.py +654 -654
  138. stubber/tools/readme.md +6 -6
  139. stubber/update_fallback.py +117 -117
  140. stubber/update_module_list.py +123 -123
  141. stubber/utils/__init__.py +6 -6
  142. stubber/utils/config.py +137 -125
  143. stubber/utils/makeversionhdr.py +54 -54
  144. stubber/utils/manifest.py +90 -90
  145. stubber/utils/post.py +80 -79
  146. stubber/utils/repos.py +156 -150
  147. stubber/utils/stubmaker.py +139 -139
  148. stubber/utils/typed_config_toml.py +80 -77
  149. stubber/variants.py +106 -106
  150. micropython_stubber-1.23.1.dist-info/RECORD +0 -159
  151. micropython_stubber-1.23.1.dist-info/entry_points.txt +0 -3
  152. mpflash/basicgit.py +0 -288
  153. {micropython_stubber-1.23.1.dist-info → micropython_stubber-1.23.2.dist-info}/WHEEL +0 -0
@@ -1,219 +1,224 @@
1
- from pathlib import Path
2
- from typing import List
3
-
4
- import rich_click as click
5
- from loguru import logger as log
6
-
7
- from mpflash.common import BootloaderMethod
8
- from mpflash.errors import MPFlashError
9
- from mpflash.mpboard_id import find_known_board
10
- from mpflash.mpremoteboard import MPRemoteBoard
11
- from mpflash.versions import clean_version
12
-
13
- from .ask_input import ask_missing_params
14
- from .cli_download import connected_ports_boards
15
- from .cli_group import cli
16
- from .cli_list import show_mcus
17
- from .common import FlashParams
18
- from .config import config
19
- from .flash import flash_list
20
- from .flash.worklist import (WorkList, full_auto_worklist, manual_worklist,
21
- single_auto_worklist)
22
-
23
- # #########################################################################################################
24
- # CLI
25
- # #########################################################################################################
26
-
27
-
28
- @cli.command(
29
- "flash",
30
- short_help="Flash one or all connected MicroPython boards with a specific firmware and version.",
31
- )
32
- @click.option(
33
- "--firmware",
34
- "-f",
35
- "fw_folder",
36
- type=click.Path(file_okay=False, dir_okay=True, path_type=Path),
37
- default=config.firmware_folder,
38
- show_default=True,
39
- help="The folder to retrieve the firmware from.",
40
- )
41
- @click.option(
42
- "--version",
43
- "-v",
44
- "version", # single version
45
- default="stable",
46
- multiple=False,
47
- show_default=True,
48
- help="The version of MicroPython to flash.",
49
- metavar="SEMVER, 'stable', 'preview' or '?'",
50
- )
51
- @click.option(
52
- "--serial",
53
- "--serial-port",
54
- "-s",
55
- "serial",
56
- default=["*"],
57
- multiple=True,
58
- show_default=True,
59
- help="Which serial port(s) to flash",
60
- metavar="SERIALPORT",
61
- )
62
- @click.option(
63
- "--ignore",
64
- "-i",
65
- is_eager=True,
66
- help="Serial port(s) to ignore. Defaults to MPFLASH_IGNORE.",
67
- multiple=True,
68
- default=[],
69
- envvar="MPFLASH_IGNORE",
70
- show_default=True,
71
- metavar="SERIALPORT",
72
- )
73
- @click.option(
74
- "--port",
75
- "-p",
76
- "ports",
77
- help="The MicroPython port to flash",
78
- metavar="PORT",
79
- default=[],
80
- multiple=True,
81
- )
82
- @click.option(
83
- "--board",
84
- "-b",
85
- "board", # single board
86
- multiple=False,
87
- help="The MicroPython board ID to flash. If not specified will try to read the BOARD_ID from the connected MCU.",
88
- metavar="BOARD_ID or ?",
89
- )
90
- @click.option(
91
- "--cpu",
92
- "--chip",
93
- "-c",
94
- "cpu",
95
- help="The CPU type to flash. If not specified will try to read the CPU from the connected MCU.",
96
- metavar="CPU",
97
- )
98
- @click.option(
99
- "--erase/--no-erase",
100
- default=True,
101
- show_default=True,
102
- help="""Erase flash before writing new firmware. (Not supported on UF2 boards)""",
103
- )
104
- @click.option(
105
- "--bootloader",
106
- "-bl",
107
- "bootloader",
108
- type=click.Choice([e.value for e in BootloaderMethod]),
109
- default="auto",
110
- show_default=True,
111
- help="""How to enter the (MicroPython) bootloader before flashing.""",
112
- )
113
- def cli_flash_board(**kwargs) -> int:
114
- # version to versions, board to boards
115
- kwargs["versions"] = [kwargs.pop("version")] if kwargs["version"] != None else []
116
- if kwargs["board"] is None:
117
- kwargs["boards"] = []
118
- kwargs.pop("board")
119
- else:
120
- kwargs["boards"] = [kwargs.pop("board")]
121
-
122
- params = FlashParams(**kwargs)
123
- params.versions = list(params.versions)
124
- params.ports = list(params.ports)
125
- params.boards = list(params.boards)
126
- params.serial = list(params.serial)
127
- params.ignore = list(params.ignore)
128
- params.bootloader = BootloaderMethod(params.bootloader)
129
-
130
- # make it simple for the user to flash one board by asking for the serial port if not specified
131
- if params.boards == ["?"] and params.serial == "*":
132
- params.serial = ["?"]
133
-
134
- # Detect connected boards if not specified,
135
- # and ask for input if boards cannot be detected
136
- all_boards: List[MPRemoteBoard] = []
137
- if not params.boards:
138
- # nothing specified - detect connected boards
139
- params.ports, params.boards, all_boards = connected_ports_boards(include=params.ports, ignore=params.ignore)
140
- if params.boards == []:
141
- # No MicroPython boards detected, but it could be unflashed or in bootloader mode
142
- # Ask for serial port and board_id to flash
143
- params.serial = ["?"]
144
- params.boards = ["?"]
145
- # assume manual mode if no board is detected
146
- params.bootloader = BootloaderMethod("manual")
147
- else:
148
- resolve_board_ids(params)
149
-
150
- # Ask for missing input if needed
151
- params = ask_missing_params(params)
152
- if not params: # Cancelled by user
153
- return 2
154
- # TODO: Just in time Download of firmware
155
-
156
- assert isinstance(params, FlashParams)
157
-
158
- if len(params.versions) > 1:
159
- log.error(f"Only one version can be flashed at a time, not {params.versions}")
160
- raise MPFlashError("Only one version can be flashed at a time")
161
-
162
- params.versions = [clean_version(v) for v in params.versions]
163
- worklist: WorkList = []
164
- # if serial port == auto and there are one or more specified/detected boards
165
- if params.serial == ["*"] and params.boards:
166
- if not all_boards:
167
- log.trace("No boards detected yet, scanning for connected boards")
168
- _, _, all_boards = connected_ports_boards(include=params.ports, ignore=params.ignore)
169
- worklist = full_auto_worklist(
170
- all_boards=all_boards,
171
- version=params.versions[0],
172
- fw_folder=params.fw_folder,
173
- include=params.serial,
174
- ignore=params.ignore,
175
- )
176
- elif params.versions[0] and params.boards[0] and params.serial:
177
- # A one or more serial port including the board / variant
178
- worklist = manual_worklist(
179
- params.serial[0],
180
- board_id=params.boards[0],
181
- version=params.versions[0],
182
- fw_folder=params.fw_folder,
183
- )
184
- else:
185
- # just this serial port on auto
186
- worklist = single_auto_worklist(
187
- serial=params.serial[0],
188
- version=params.versions[0],
189
- fw_folder=params.fw_folder,
190
- )
191
-
192
- if flashed := flash_list(
193
- worklist,
194
- params.fw_folder,
195
- params.erase,
196
- params.bootloader,
197
- ):
198
- log.info(f"Flashed {len(flashed)} boards")
199
- show_mcus(flashed, title="Updated boards after flashing")
200
- return 0
201
- else:
202
- log.error("No boards were flashed")
203
- return 1
204
-
205
-
206
- def resolve_board_ids(params):
207
- """Resolve board descriptions to board_id, and remove empty strings from list of boards"""
208
- for board_id in params.boards:
209
- if board_id == "":
210
- params.boards.remove(board_id)
211
- continue
212
- if " " in board_id:
213
- try:
214
- if info := find_known_board(board_id):
215
- log.info(f"Resolved board description: {info.board_id}")
216
- params.boards.remove(board_id)
217
- params.boards.append(info.board_id)
218
- except Exception as e:
219
- log.warning(f"Unable to resolve board description: {e}")
1
+ from pathlib import Path
2
+ from typing import List
3
+
4
+ import rich_click as click
5
+ from loguru import logger as log
6
+
7
+ from mpflash.ask_input import ask_missing_params
8
+ from mpflash.cli_download import connected_ports_boards
9
+ from mpflash.cli_group import cli
10
+ from mpflash.cli_list import show_mcus
11
+ from mpflash.common import BootloaderMethod, FlashParams, Params
12
+ from mpflash.config import config
13
+ from mpflash.errors import MPFlashError
14
+ from mpflash.flash import flash_list
15
+ from mpflash.flash.worklist import WorkList, full_auto_worklist, manual_worklist, single_auto_worklist
16
+ from mpflash.mpboard_id import find_known_board
17
+ from mpflash.mpremoteboard import MPRemoteBoard
18
+ from mpflash.versions import clean_version
19
+
20
+ # #########################################################################################################
21
+ # CLI
22
+ # #########################################################################################################
23
+
24
+
25
+ @cli.command(
26
+ "flash",
27
+ short_help="Flash one or all connected MicroPython boards with a specific firmware and version.",
28
+ )
29
+ @click.option(
30
+ "--firmware",
31
+ "-f",
32
+ "fw_folder",
33
+ type=click.Path(file_okay=False, dir_okay=True, path_type=Path),
34
+ default=config.firmware_folder,
35
+ show_default=True,
36
+ help="The folder to retrieve the firmware from.",
37
+ )
38
+ @click.option(
39
+ "--version",
40
+ "-v",
41
+ "version", # single version
42
+ default="stable",
43
+ multiple=False,
44
+ show_default=True,
45
+ help="The version of MicroPython to flash.",
46
+ metavar="SEMVER, 'stable', 'preview' or '?'",
47
+ )
48
+ @click.option(
49
+ "--serial",
50
+ "--serial-port",
51
+ "-s",
52
+ "serial",
53
+ default=["*"],
54
+ multiple=True,
55
+ show_default=True,
56
+ help="Which serial port(s) (or globs) to flash",
57
+ metavar="SERIALPORT",
58
+ )
59
+ @click.option(
60
+ "--ignore",
61
+ "-i",
62
+ is_eager=True,
63
+ help="Serial port(s) to ignore. Defaults to MPFLASH_IGNORE.",
64
+ multiple=True,
65
+ default=[],
66
+ envvar="MPFLASH_IGNORE",
67
+ show_default=True,
68
+ metavar="SERIALPORT",
69
+ )
70
+ @click.option(
71
+ "--bluetooth/--no-bluetooth",
72
+ "-b/-nb",
73
+ is_flag=True,
74
+ default=False,
75
+ show_default=True,
76
+ help="""Include bluetooth ports in the list""",
77
+ )
78
+ @click.option(
79
+ "--port",
80
+ "-p",
81
+ "ports",
82
+ help="The MicroPython port to flash",
83
+ metavar="PORT",
84
+ default=[],
85
+ multiple=True,
86
+ )
87
+ @click.option(
88
+ "--board",
89
+ "-b",
90
+ "board", # single board
91
+ multiple=False,
92
+ help="The MicroPython board ID to flash. If not specified will try to read the BOARD_ID from the connected MCU.",
93
+ metavar="BOARD_ID or ?",
94
+ )
95
+ @click.option(
96
+ "--cpu",
97
+ "--chip",
98
+ "-c",
99
+ "cpu",
100
+ help="The CPU type to flash. If not specified will try to read the CPU from the connected MCU.",
101
+ metavar="CPU",
102
+ )
103
+ @click.option(
104
+ "--erase/--no-erase",
105
+ default=True,
106
+ show_default=True,
107
+ help="""Erase flash before writing new firmware. (Not supported on UF2 boards)""",
108
+ )
109
+ @click.option(
110
+ "--bootloader",
111
+ "-bl",
112
+ "bootloader",
113
+ type=click.Choice([e.value for e in BootloaderMethod]),
114
+ default="auto",
115
+ show_default=True,
116
+ help="""How to enter the (MicroPython) bootloader before flashing.""",
117
+ )
118
+ def cli_flash_board(**kwargs) -> int:
119
+ # version to versions, board to boards
120
+ kwargs["versions"] = [kwargs.pop("version")] if kwargs["version"] != None else []
121
+ if kwargs["board"] is None:
122
+ kwargs["boards"] = []
123
+ kwargs.pop("board")
124
+ else:
125
+ kwargs["boards"] = [kwargs.pop("board")]
126
+
127
+ params = FlashParams(**kwargs)
128
+ params.versions = list(params.versions)
129
+ params.ports = list(params.ports)
130
+ params.boards = list(params.boards)
131
+ params.serial = list(params.serial)
132
+ params.ignore = list(params.ignore)
133
+ params.bootloader = BootloaderMethod(params.bootloader)
134
+
135
+ # make it simple for the user to flash one board by asking for the serial port if not specified
136
+ if params.boards == ["?"] and params.serial == "*":
137
+ params.serial = ["?"]
138
+
139
+ # Detect connected boards if not specified,
140
+ # and ask for input if boards cannot be detected
141
+ all_boards: List[MPRemoteBoard] = []
142
+ if not params.boards:
143
+ # nothing specified - detect connected boards
144
+ params.ports, params.boards, all_boards = connected_ports_boards(include=params.ports, ignore=params.ignore, bluetooth=params.bluetooth)
145
+ if params.boards == []:
146
+ # No MicroPython boards detected, but it could be unflashed or in bootloader mode
147
+ # Ask for serial port and board_id to flash
148
+ params.serial = ["?"]
149
+ params.boards = ["?"]
150
+ # assume manual mode if no board is detected
151
+ params.bootloader = BootloaderMethod("manual")
152
+ else:
153
+ resolve_board_ids(params)
154
+
155
+ # Ask for missing input if needed
156
+ params = ask_missing_params(params)
157
+ if not params: # Cancelled by user
158
+ return 2
159
+ # TODO: Just in time Download of firmware
160
+
161
+ assert isinstance(params, FlashParams)
162
+
163
+ if len(params.versions) > 1:
164
+ log.error(f"Only one version can be flashed at a time, not {params.versions}")
165
+ raise MPFlashError("Only one version can be flashed at a time")
166
+
167
+ params.versions = [clean_version(v) for v in params.versions]
168
+ worklist: WorkList = []
169
+ # if serial port == auto and there are one or more specified/detected boards
170
+ if params.serial == ["*"] and params.boards:
171
+ if not all_boards:
172
+ log.trace("No boards detected yet, scanning for connected boards")
173
+ _, _, all_boards = connected_ports_boards(include=params.ports, ignore=params.ignore)
174
+ worklist = full_auto_worklist(
175
+ all_boards=all_boards,
176
+ version=params.versions[0],
177
+ fw_folder=params.fw_folder,
178
+ include=params.serial,
179
+ ignore=params.ignore,
180
+ )
181
+ elif params.versions[0] and params.boards[0] and params.serial:
182
+ # A one or more serial port including the board / variant
183
+ worklist = manual_worklist(
184
+ params.serial[0],
185
+ board_id=params.boards[0],
186
+ version=params.versions[0],
187
+ fw_folder=params.fw_folder,
188
+ )
189
+ else:
190
+ # just this serial port on auto
191
+ worklist = single_auto_worklist(
192
+ serial=params.serial[0],
193
+ version=params.versions[0],
194
+ fw_folder=params.fw_folder,
195
+ )
196
+
197
+ if flashed := flash_list(
198
+ worklist,
199
+ params.fw_folder,
200
+ params.erase,
201
+ params.bootloader,
202
+ ):
203
+ log.info(f"Flashed {len(flashed)} boards")
204
+ show_mcus(flashed, title="Updated boards after flashing")
205
+ return 0
206
+ else:
207
+ log.error("No boards were flashed")
208
+ return 1
209
+
210
+
211
+ def resolve_board_ids(params: Params):
212
+ """Resolve board descriptions to board_id, and remove empty strings from list of boards"""
213
+ for board_id in params.boards:
214
+ if board_id == "":
215
+ params.boards.remove(board_id)
216
+ continue
217
+ if " " in board_id:
218
+ try:
219
+ if info := find_known_board(board_id):
220
+ log.info(f"Resolved board description: {info.board_id}")
221
+ params.boards.remove(board_id)
222
+ params.boards.append(info.board_id)
223
+ except Exception as e:
224
+ log.warning(f"Unable to resolve board description: {e}")