micropython-stubber 1.20.4__py3-none-any.whl → 1.20.5__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 (44) hide show
  1. {micropython_stubber-1.20.4.dist-info → micropython_stubber-1.20.5.dist-info}/METADATA +4 -4
  2. {micropython_stubber-1.20.4.dist-info → micropython_stubber-1.20.5.dist-info}/RECORD +44 -39
  3. mpflash/mpflash/ask_input.py +24 -14
  4. mpflash/mpflash/bootloader/__init__.py +36 -0
  5. mpflash/mpflash/bootloader/manual.py +102 -0
  6. mpflash/mpflash/bootloader/micropython.py +10 -0
  7. mpflash/mpflash/bootloader/touch1200.py +45 -0
  8. mpflash/mpflash/cli_download.py +1 -0
  9. mpflash/mpflash/cli_flash.py +16 -9
  10. mpflash/mpflash/cli_group.py +10 -4
  11. mpflash/mpflash/cli_list.py +6 -2
  12. mpflash/mpflash/cli_main.py +5 -2
  13. mpflash/mpflash/common.py +14 -1
  14. mpflash/mpflash/config.py +17 -1
  15. mpflash/mpflash/download.py +2 -3
  16. mpflash/mpflash/downloaded.py +3 -3
  17. mpflash/mpflash/errors.py +5 -1
  18. mpflash/mpflash/flash.py +10 -27
  19. mpflash/mpflash/flash_uf2_macos.py +0 -3
  20. mpflash/mpflash/vendor/click_aliases.py +91 -0
  21. mpflash/poetry.lock +102 -137
  22. mpflash/pyproject.toml +1 -1
  23. stubber/__init__.py +1 -1
  24. stubber/board/createstubs.py +3 -4
  25. stubber/board/createstubs_db.py +4 -5
  26. stubber/board/createstubs_db_min.py +1 -1
  27. stubber/board/createstubs_db_mpy.mpy +0 -0
  28. stubber/board/createstubs_mem.py +4 -5
  29. stubber/board/createstubs_mem_min.py +1 -1
  30. stubber/board/createstubs_mem_mpy.mpy +0 -0
  31. stubber/board/createstubs_min.py +1 -1
  32. stubber/board/createstubs_mpy.mpy +0 -0
  33. stubber/bulk/mcu_stubber.py +0 -1
  34. stubber/codemod/_partials/__init__.py +0 -2
  35. stubber/publish/candidates.py +7 -28
  36. stubber/publish/enums.py +0 -6
  37. stubber/publish/package.py +15 -46
  38. stubber/publish/publish.py +1 -2
  39. stubber/rst/lookup.py +7 -7
  40. stubber/rst/reader.py +26 -27
  41. stubber/update_module_list.py +0 -2
  42. {micropython_stubber-1.20.4.dist-info → micropython_stubber-1.20.5.dist-info}/LICENSE +0 -0
  43. {micropython_stubber-1.20.4.dist-info → micropython_stubber-1.20.5.dist-info}/WHEEL +0 -0
  44. {micropython_stubber-1.20.4.dist-info → micropython_stubber-1.20.5.dist-info}/entry_points.txt +0 -0
mpflash/mpflash/common.py CHANGED
@@ -2,6 +2,7 @@ import fnmatch
2
2
  import os
3
3
  import sys
4
4
  from dataclasses import dataclass, field
5
+ from enum import Enum
5
6
  from pathlib import Path
6
7
  from typing import List, Optional, Union
7
8
 
@@ -90,14 +91,26 @@ class DownloadParams(Params):
90
91
  force: bool = False
91
92
 
92
93
 
94
+ class BootloaderMethod(Enum):
95
+ MANUAL = "manual"
96
+ MPY = "mpy"
97
+ TOUCH_1200 = "touch1200"
98
+ NONE = "none"
99
+
100
+
101
+
93
102
  @dataclass
94
103
  class FlashParams(Params):
95
104
  """Parameters for flashing a board"""
96
105
 
97
106
  erase: bool = True
98
- bootloader: bool = True
107
+ bootloader: BootloaderMethod = BootloaderMethod.NONE
99
108
  cpu: str = ""
100
109
 
110
+ def __post_init__(self):
111
+ if isinstance(self.bootloader, str):
112
+ self.bootloader = BootloaderMethod(self.bootloader)
113
+
101
114
 
102
115
  ParamType = Union[DownloadParams, FlashParams]
103
116
 
mpflash/mpflash/config.py CHANGED
@@ -1,11 +1,14 @@
1
1
  """centralized configuration for mpflash"""
2
2
 
3
+ import os
3
4
  from pathlib import Path
4
5
  from typing import List
5
6
 
6
7
  import pkg_resources
7
8
  import platformdirs
8
9
 
10
+ from mpflash.logger import log
11
+
9
12
 
10
13
  def get_version():
11
14
  name = __package__ or "mpflash"
@@ -21,10 +24,23 @@ class MPtoolConfig:
21
24
  quiet: bool = False
22
25
  verbose: bool = False
23
26
  ignore_ports: List[str] = []
24
- interactive: bool = True
25
27
  firmware_folder: Path = platformdirs.user_downloads_path() / "firmware"
26
28
  # test options specified on the commandline
27
29
  tests: List[str] = []
30
+ _interactive: bool = True
31
+
32
+ @property
33
+ def interactive(self):
34
+ # No interactions in CI
35
+ if os.getenv('GITHUB_ACTIONS') == 'true':
36
+ log.warning("Disabling interactive mode in CI")
37
+ return False
38
+ return self._interactive
39
+
40
+ @interactive.setter
41
+ def interactive(self, value:bool):
42
+ self._interactive = value
43
+
28
44
 
29
45
 
30
46
  config = MPtoolConfig()
@@ -19,7 +19,6 @@ from loguru import logger as log
19
19
  from rich.progress import track
20
20
 
21
21
  from mpflash.common import PORT_FWTYPES, FWInfo
22
- from mpflash.downloaded import clean_downloaded_firmwares
23
22
  from mpflash.errors import MPFlashError
24
23
  from mpflash.mpboard_id import get_known_ports
25
24
  from mpflash.vendor.versions import clean_version
@@ -246,8 +245,8 @@ def download_firmwares(
246
245
  continue
247
246
  writer.write(board.to_dict())
248
247
  downloaded += 1
249
- if downloaded > 0:
250
- clean_downloaded_firmwares(firmware_folder)
248
+ # if downloaded > 0:
249
+ # clean_downloaded_firmwares(firmware_folder)
251
250
  log.success(f"Downloaded {downloaded} firmwares, skipped {skipped} existing files.")
252
251
  return downloaded + skipped
253
252
 
@@ -103,9 +103,9 @@ def filter_downloaded_fwlist(
103
103
  # never get a preview for an older version
104
104
  fw_list = [fw for fw in fw_list if fw.preview]
105
105
  else:
106
- # FWInfo version has no v1.2.3 prefix
107
- _version = {clean_version(version, drop_v=True), clean_version(version, drop_v=False)}
108
- fw_list = [fw for fw in fw_list if fw.version in _version]
106
+ # older FWInfo version has no v1.2.3 prefix
107
+ either = [clean_version(version, drop_v=False), clean_version(version, drop_v=True)]
108
+ fw_list = [fw for fw in fw_list if fw.version in either]
109
109
  log.trace(f"Filtering firmware for {version} : {len(fw_list)} found.")
110
110
  # filter by port
111
111
  if port:
mpflash/mpflash/errors.py CHANGED
@@ -2,4 +2,8 @@
2
2
 
3
3
 
4
4
  class MPFlashError(Exception):
5
- pass
5
+ """Base class for exceptions in this module."""
6
+
7
+ def __init__(self, message: str):
8
+ self.message = message
9
+ super().__init__(message)
mpflash/mpflash/flash.py CHANGED
@@ -1,10 +1,9 @@
1
- import time
2
1
  from pathlib import Path
3
2
 
4
3
  from loguru import logger as log
5
4
 
6
- from mpflash.common import PORT_FWTYPES
7
- from mpflash.mpremoteboard import MPRemoteBoard
5
+ from mpflash.bootloader import enter_bootloader
6
+ from mpflash.common import PORT_FWTYPES, BootloaderMethod
8
7
 
9
8
  from .flash_esp import flash_esp
10
9
  from .flash_stm32 import flash_stm32
@@ -14,13 +13,15 @@ from .worklist import WorkList
14
13
  # #########################################################################################################
15
14
 
16
15
 
16
+
17
17
  def flash_list(
18
18
  todo: WorkList,
19
19
  fw_folder: Path,
20
20
  erase: bool,
21
- bootloader: bool,
21
+ bootloader: BootloaderMethod,
22
22
  ):
23
23
  """Flash a list of boards with the specified firmware."""
24
+ UF2_PORTS = [port for port, exts in PORT_FWTYPES.items() if ".uf2" in exts]
24
25
  flashed = []
25
26
  for mcu, fw_info in todo:
26
27
  fw_file = fw_folder / fw_info.filename
@@ -30,14 +31,13 @@ def flash_list(
30
31
  log.info(f"Updating {mcu.board} on {mcu.serialport} to {fw_info.version}")
31
32
  updated = None
32
33
  # try:
33
- if mcu.port in [port for port, exts in PORT_FWTYPES.items() if ".uf2" in exts] and fw_file.suffix == ".uf2":
34
- # any .uf2 port ["samd", "rp2", "nrf"]:
35
- if bootloader:
36
- enter_bootloader(mcu)
34
+ if mcu.port in UF2_PORTS and fw_file.suffix == ".uf2":
35
+ if not enter_bootloader(mcu, bootloader):
36
+ continue
37
37
  updated = flash_uf2(mcu, fw_file=fw_file, erase=erase)
38
38
  elif mcu.port in ["stm32"]:
39
- if bootloader:
40
- enter_bootloader(mcu)
39
+ if not enter_bootloader(mcu, bootloader):
40
+ continue
41
41
  updated = flash_stm32(mcu, fw_file, erase=erase)
42
42
  elif mcu.port in ["esp32", "esp8266"]:
43
43
  # bootloader is handled by esptool for esp32/esp8266
@@ -50,20 +50,3 @@ def flash_list(
50
50
  else:
51
51
  log.error(f"Failed to flash {mcu.board} on {mcu.serialport}")
52
52
  return flashed
53
-
54
-
55
- def enter_bootloader(mcu: MPRemoteBoard, timeout: int = 10, wait_after: int = 2):
56
- """Enter the bootloader mode for the board"""
57
- log.info(f"Entering bootloader on {mcu.board} on {mcu.serialport}")
58
- mcu.run_command("bootloader", timeout=timeout)
59
- time.sleep(wait_after)
60
-
61
-
62
- # TODO:
63
- # flash from some sort of queue to allow different images to be flashed to the same board
64
- # - flash variant 1
65
- # - stub variant 1
66
- # - flash variant 2
67
- # - stub variant 2
68
- #
69
- # JIT download / download any missing firmwares based on the detected boards
@@ -3,15 +3,12 @@
3
3
  # sourcery skip: snake-case-functions
4
4
  from __future__ import annotations
5
5
 
6
- import sys
7
6
  import time
8
7
  from pathlib import Path
9
8
  from typing import Optional
10
9
 
11
- from loguru import logger as log
12
10
  from rich.progress import track
13
11
 
14
- from .flash_uf2_boardid import get_board_id
15
12
 
16
13
 
17
14
  def wait_for_UF2_macos(s_max: int = 10) -> Optional[Path]:
@@ -0,0 +1,91 @@
1
+ # Copyright (c) 2016 Robbin Bonthond
2
+
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+
10
+ # The above copyright notice and this permission notice shall be included in all
11
+ # copies or substantial portions of the Software.
12
+ # ------------------------------------------------------------------------------------
13
+ # modified to avoid conflcts with rich_click
14
+
15
+ # sourcery skip: assign-if-exp, use-named-expression
16
+
17
+ import rich_click as click
18
+
19
+ _click7 = click.__version__[0] >= "7"
20
+
21
+
22
+ class ClickAliasedGroup(click.RichGroup):
23
+ def __init__(self, *args, **kwargs):
24
+ super().__init__(*args, **kwargs)
25
+ self._commands = {}
26
+ self._aliases = {}
27
+
28
+ def add_command(self, *args, **kwargs):
29
+ aliases = kwargs.pop("aliases", [])
30
+ super().add_command(*args, **kwargs)
31
+ if aliases:
32
+ cmd = args[0]
33
+ name = args[1] if len(args) > 1 else None
34
+ name = name or cmd.name
35
+ if name is None:
36
+ raise TypeError("Command has no name.")
37
+
38
+ self._commands[name] = aliases
39
+ for alias in aliases:
40
+ self._aliases[alias] = cmd.name
41
+
42
+ def command(self, *args, **kwargs):
43
+ aliases = kwargs.pop("aliases", [])
44
+ decorator = super().command(*args, **kwargs)
45
+ if not aliases:
46
+ return decorator
47
+
48
+ def _decorator(f):
49
+ cmd = decorator(f)
50
+ if aliases:
51
+ self._commands[cmd.name] = aliases
52
+ for alias in aliases:
53
+ self._aliases[alias] = cmd.name
54
+ return cmd
55
+
56
+ return _decorator
57
+
58
+ def group(self, *args, **kwargs):
59
+ aliases = kwargs.pop("aliases", [])
60
+ decorator = super().group(*args, **kwargs)
61
+ if not aliases:
62
+ return decorator
63
+
64
+ def _decorator(f):
65
+ cmd = decorator(f)
66
+ if aliases:
67
+ self._commands[cmd.name] = aliases
68
+ for alias in aliases:
69
+ self._aliases[alias] = cmd.name
70
+ return cmd
71
+
72
+ return _decorator
73
+
74
+ def resolve_alias(self, cmd_name):
75
+ if cmd_name in self._aliases:
76
+ return self._aliases[cmd_name]
77
+ return cmd_name
78
+
79
+ def get_command(self, ctx, cmd_name):
80
+ cmd_name = self.resolve_alias(cmd_name)
81
+ command = super().get_command(ctx, cmd_name)
82
+ if command:
83
+ return command
84
+ return None
85
+
86
+ # def format_commands(self, ctx, formatter):
87
+ # TODO: output alias with commands - but that is a significant re-write
88
+ # for now add alias to help text
89
+
90
+
91
+ # ------------------------------------------------------------------------------------