From 7629957433611523a7e412c4313994c1d7da5f34 Mon Sep 17 00:00:00 2001 From: David Lechner Date: Sat, 18 Jan 2025 13:59:50 -0600 Subject: [PATCH 1/8] pybricksdev: use absolute imports Change imports from relative to absolute. Quick fix tools in the IDE will automatically generate absolute imports so if we stick with that we can use the tools without having to manually fix the imports. Also absolute imports can be easier to understand if you don't know the folder structure by heart. --- pybricksdev/__main__.py | 2 +- pybricksdev/_vendored/pynxt/flash.py | 2 +- pybricksdev/_vendored/pynxt/samba.py | 2 +- pybricksdev/ble/__init__.py | 4 +-- pybricksdev/ble/lwp3/__init__.py | 2 +- pybricksdev/ble/lwp3/bootloader.py | 2 +- pybricksdev/ble/lwp3/messages.py | 4 +-- pybricksdev/ble/oad/__init__.py | 8 +++--- pybricksdev/ble/oad/control_point.py | 2 +- pybricksdev/ble/oad/firmware.py | 2 +- pybricksdev/ble/oad/image_block.py | 2 +- pybricksdev/ble/oad/image_identify.py | 2 +- pybricksdev/cli/__init__.py | 28 ++++++++++----------- pybricksdev/cli/flash.py | 36 +++++++++++++-------------- pybricksdev/cli/lwp3/repl.py | 6 ++--- pybricksdev/cli/oad.py | 13 +++++++--- pybricksdev/compile.py | 2 +- pybricksdev/connections/ev3.py | 2 +- pybricksdev/connections/lego.py | 4 +-- pybricksdev/connections/pybricks.py | 14 +++++------ pybricksdev/dfu.py | 6 ++--- pybricksdev/firmware.py | 4 +-- pybricksdev/flash.py | 6 ++--- 23 files changed, 80 insertions(+), 75 deletions(-) diff --git a/pybricksdev/__main__.py b/pybricksdev/__main__.py index c120afb..102b1de 100644 --- a/pybricksdev/__main__.py +++ b/pybricksdev/__main__.py @@ -3,7 +3,7 @@ """Main entry point for running pybricksdev as a module.""" -from .cli import main +from pybricksdev.cli import main if __name__ == "__main__": main() diff --git a/pybricksdev/_vendored/pynxt/flash.py b/pybricksdev/_vendored/pynxt/flash.py index 06efa2e..9659e04 100644 --- a/pybricksdev/_vendored/pynxt/flash.py +++ b/pybricksdev/_vendored/pynxt/flash.py @@ -4,7 +4,7 @@ import math from importlib.resources import read_binary -from . import resources +from pybricksdev._vendored.pynxt import resources # Mnemonics for the addresses of the various registers used by the flash # controller. diff --git a/pybricksdev/_vendored/pynxt/samba.py b/pybricksdev/_vendored/pynxt/samba.py index 4a0c679..576415b 100644 --- a/pybricksdev/_vendored/pynxt/samba.py +++ b/pybricksdev/_vendored/pynxt/samba.py @@ -3,7 +3,7 @@ import struct -from . import lowlevel +from pybricksdev._vendored.pynxt import lowlevel ATMEL_VENDOR_ID = 0x03EB SAMBA_PRODUCT_ID = 0x6124 diff --git a/pybricksdev/ble/__init__.py b/pybricksdev/ble/__init__.py index f68ff21..a097fcd 100644 --- a/pybricksdev/ble/__init__.py +++ b/pybricksdev/ble/__init__.py @@ -9,8 +9,8 @@ from bleak.backends.device import BLEDevice from bleak.backends.scanner import AdvertisementData -from ..tools import chunk -from .pybricks import PYBRICKS_SERVICE_UUID +from pybricksdev.ble.pybricks import PYBRICKS_SERVICE_UUID +from pybricksdev.tools import chunk logger = logging.getLogger(__name__) diff --git a/pybricksdev/ble/lwp3/__init__.py b/pybricksdev/ble/lwp3/__init__.py index 416567a..e253897 100644 --- a/pybricksdev/ble/lwp3/__init__.py +++ b/pybricksdev/ble/lwp3/__init__.py @@ -6,7 +6,7 @@ communications with devices that provide the LEGO Wireless Protocol v3. """ -from .bytecodes import Capabilities, HubKind, LastNetwork, Status +from pybricksdev.ble.lwp3.bytecodes import Capabilities, HubKind, LastNetwork, Status # LEGO Wireless Protocol v3 is defined at: # https://lego.github.io/lego-ble-wireless-protocol-docs/ diff --git a/pybricksdev/ble/lwp3/bootloader.py b/pybricksdev/ble/lwp3/bootloader.py index b6035ba..fcfb4ac 100644 --- a/pybricksdev/ble/lwp3/bootloader.py +++ b/pybricksdev/ble/lwp3/bootloader.py @@ -8,7 +8,7 @@ from enum import IntEnum -from .bytecodes import Capabilities, HubKind, Version +from pybricksdev.ble.lwp3.bytecodes import Capabilities, HubKind, Version # Bootloader characteristic bytecodes diff --git a/pybricksdev/ble/lwp3/messages.py b/pybricksdev/ble/lwp3/messages.py index fe85479..a2dcf5f 100644 --- a/pybricksdev/ble/lwp3/messages.py +++ b/pybricksdev/ble/lwp3/messages.py @@ -15,8 +15,7 @@ from enum import IntEnum from typing import Any, Dict, List, NamedTuple, Optional, Tuple, Type, Union, overload -from ...tools.checksum import xor_bytes -from .bytecodes import ( +from pybricksdev.ble.lwp3.bytecodes import ( MAX_NAME_SIZE, AlertKind, AlertOperation, @@ -52,6 +51,7 @@ Version, VirtualPortSetupCommand, ) +from pybricksdev.tools.checksum import xor_bytes class AbstractMessage(abc.ABC): diff --git a/pybricksdev/ble/oad/__init__.py b/pybricksdev/ble/oad/__init__.py index d387859..45ff423 100644 --- a/pybricksdev/ble/oad/__init__.py +++ b/pybricksdev/ble/oad/__init__.py @@ -7,10 +7,10 @@ https://software-dl.ti.com/lprf/sdg-latest/html/oad-ble-stack-3.x/oad_profile.html """ -from ._common import OADReturn, oad_uuid -from .control_point import OADControlPoint -from .image_block import OADImageBlock -from .image_identify import OADImageIdentify +from pybricksdev.ble.oad._common import OADReturn, oad_uuid +from pybricksdev.ble.oad.control_point import OADControlPoint +from pybricksdev.ble.oad.image_block import OADImageBlock +from pybricksdev.ble.oad.image_identify import OADImageIdentify __all__ = [ "OAD_SERVICE_UUID", diff --git a/pybricksdev/ble/oad/control_point.py b/pybricksdev/ble/oad/control_point.py index 6bd8016..8f03aea 100644 --- a/pybricksdev/ble/oad/control_point.py +++ b/pybricksdev/ble/oad/control_point.py @@ -8,7 +8,7 @@ from bleak import BleakClient from bleak.exc import BleakError -from ._common import OADReturn, SoftwareVersion, oad_uuid +from pybricksdev.ble.oad._common import OADReturn, SoftwareVersion, oad_uuid __all__ = ["OADControlPoint"] diff --git a/pybricksdev/ble/oad/firmware.py b/pybricksdev/ble/oad/firmware.py index 42752cf..6395193 100644 --- a/pybricksdev/ble/oad/firmware.py +++ b/pybricksdev/ble/oad/firmware.py @@ -4,7 +4,7 @@ import struct from typing import NamedTuple -from ._common import ImageInfo, SoftwareVersion +from pybricksdev.ble.oad._common import ImageInfo, SoftwareVersion # More info at: # https://github.com/TexasInstruments/simplelink-lowpower-f3-sdk/blob/main/tools/common/oad/oad_image_tool.py diff --git a/pybricksdev/ble/oad/image_block.py b/pybricksdev/ble/oad/image_block.py index 4b454bc..6db3b31 100644 --- a/pybricksdev/ble/oad/image_block.py +++ b/pybricksdev/ble/oad/image_block.py @@ -10,7 +10,7 @@ from bleak import BleakClient -from ._common import oad_uuid +from pybricksdev.ble.oad._common import oad_uuid __all__ = ["OADImageBlock"] diff --git a/pybricksdev/ble/oad/image_identify.py b/pybricksdev/ble/oad/image_identify.py index 1a12390..0c96143 100644 --- a/pybricksdev/ble/oad/image_identify.py +++ b/pybricksdev/ble/oad/image_identify.py @@ -13,7 +13,7 @@ from bleak import BleakClient from bleak.exc import BleakError -from ._common import ImageInfo, OADReturn, SoftwareVersion, oad_uuid +from pybricksdev.ble.oad._common import ImageInfo, OADReturn, SoftwareVersion, oad_uuid __all__ = ["OADImageIdentify"] diff --git a/pybricksdev/cli/__init__.py b/pybricksdev/cli/__init__.py index ee80357..8fe8fe3 100644 --- a/pybricksdev/cli/__init__.py +++ b/pybricksdev/cli/__init__.py @@ -18,8 +18,8 @@ import argcomplete from argcomplete.completers import FilesCompleter -from .. import __name__ as MODULE_NAME -from .. import __version__ as MODULE_VERSION +from pybricksdev import __name__ as MODULE_NAME +from pybricksdev import __version__ as MODULE_VERSION PROG_NAME = ( f"{path.basename(sys.executable)} -m {MODULE_NAME}" @@ -112,7 +112,7 @@ def add_parser(self, subparsers: argparse._SubParsersAction): parser.tool = self async def run(self, args: argparse.Namespace): - from ..compile import compile_multi_file, print_mpy + from pybricksdev.compile import compile_multi_file, print_mpy with _get_script_path(args.file) as script_path: mpy = await compile_multi_file(script_path, args.abi) @@ -171,10 +171,10 @@ def add_parser(self, subparsers: argparse._SubParsersAction): ) async def run(self, args: argparse.Namespace): - from ..ble import find_device - from ..connections.ev3dev import EV3Connection - from ..connections.lego import REPLHub - from ..connections.pybricks import PybricksHub + from pybricksdev.ble import find_device + from pybricksdev.connections.ev3dev import EV3Connection + from pybricksdev.connections.lego import REPLHub + from pybricksdev.connections.pybricks import PybricksHub # Pick the right connection if args.conntype == "ssh": @@ -225,7 +225,7 @@ def add_parser(self, subparsers: argparse._SubParsersAction): ) def run(self, args: argparse.Namespace): - from .flash import flash_firmware + from pybricksdev.cli.flash import flash_firmware return flash_firmware(args.firmware, args.name) @@ -242,7 +242,7 @@ def add_parser(self, subparsers: argparse._SubParsersAction): ).completer = FilesCompleter(allowednames=(".bin",)) async def run(self, args: argparse.Namespace): - from ..dfu import backup_dfu + from pybricksdev.dfu import backup_dfu backup_dfu(args.firmware) @@ -262,7 +262,7 @@ def add_parser(self, subparsers: argparse._SubParsersAction): ).completer = FilesCompleter(allowednames=(".bin",)) async def run(self, args: argparse.Namespace): - from ..dfu import restore_dfu + from pybricksdev.dfu import restore_dfu restore_dfu(args.firmware) @@ -305,7 +305,7 @@ def add_parser(self, subparsers: argparse._SubParsersAction): ).completer = FilesCompleter(allowednames=(".oda",)) async def run(self, args: argparse.Namespace): - from .oad import flash_oad_image + from pybricksdev.cli.oad import flash_oad_image await flash_oad_image(args.firmware) @@ -319,7 +319,7 @@ def add_parser(self, subparsers: argparse._SubParsersAction): parser.tool = self async def run(self, args: argparse.Namespace): - from .oad import dump_oad_info + from pybricksdev.cli.oad import dump_oad_info await dump_oad_info() @@ -356,7 +356,7 @@ def add_parser(self, subparsers: argparse._SubParsersAction): parser.tool = self def run(self, args: argparse.Namespace): - from .lwp3.repl import repl, setup_repl_logging + from pybricksdev.cli.lwp3.repl import repl, setup_repl_logging setup_repl_logging() return repl() @@ -392,7 +392,7 @@ def add_parser(self, subparsers: argparse._SubParsersAction): async def run(self, args: argparse.Namespace): from importlib.resources import read_text - from .. import resources + from pybricksdev import resources print(read_text(resources, resources.UDEV_RULES)) diff --git a/pybricksdev/cli/flash.py b/pybricksdev/cli/flash.py index 1fc4c96..d10919c 100644 --- a/pybricksdev/cli/flash.py +++ b/pybricksdev/cli/flash.py @@ -19,23 +19,23 @@ from tqdm.auto import tqdm from tqdm.contrib.logging import logging_redirect_tqdm -from ..ble.lwp3 import ( +from pybricksdev.ble.lwp3 import ( LEGO_CID, LWP3_BOOTLOADER_SERVICE_UUID, LWP3_HUB_CHARACTERISTIC_UUID, LWP3_HUB_SERVICE_UUID, ) -from ..ble.lwp3 import AdvertisementData as HubAdvertisementData -from ..ble.lwp3.bootloader import BootloaderAdvertisementData -from ..ble.lwp3.bytecodes import HubKind, HubProperty -from ..ble.lwp3.messages import ( +from pybricksdev.ble.lwp3 import AdvertisementData as HubAdvertisementData +from pybricksdev.ble.lwp3.bootloader import BootloaderAdvertisementData +from pybricksdev.ble.lwp3.bytecodes import HubKind, HubProperty +from pybricksdev.ble.lwp3.messages import ( FirmwareUpdateMessage, HubPropertyRequestUpdate, HubPropertyUpdate, parse_message, ) -from ..ble.nus import NUS_RX_UUID, NUS_TX_UUID -from ..ble.pybricks import ( +from pybricksdev.ble.nus import NUS_RX_UUID, NUS_TX_UUID +from pybricksdev.ble.pybricks import ( FW_REV_UUID, PNP_ID_UUID, PYBRICKS_COMMAND_EVENT_UUID, @@ -44,13 +44,13 @@ Command, unpack_pnp_id, ) -from ..compile import compile_file -from ..connections.lego import REPLHub -from ..dfu import flash_dfu -from ..firmware import create_firmware_blob -from ..flash import BootloaderConnection -from ..tools import chunk -from ..tools.checksum import xor_bytes +from pybricksdev.compile import compile_file +from pybricksdev.connections.lego import REPLHub +from pybricksdev.dfu import flash_dfu +from pybricksdev.firmware import create_firmware_blob +from pybricksdev.flash import BootloaderConnection +from pybricksdev.tools import chunk +from pybricksdev.tools.checksum import xor_bytes logger = logging.getLogger(__name__) @@ -335,9 +335,9 @@ async def flash_nxt(firmware: bytes) -> None: firmware: A firmware blob with the NxOS header appended to the end. """ - from .._vendored.pynxt.firmware import Firmware - from .._vendored.pynxt.flash import FlashController - from .._vendored.pynxt.samba import SambaBrick, SambaOpenError + from pybricksdev._vendored.pynxt.firmware import Firmware + from pybricksdev._vendored.pynxt.flash import FlashController + from pybricksdev._vendored.pynxt.samba import SambaBrick, SambaOpenError # parse the header info = Firmware(firmware) @@ -375,7 +375,7 @@ async def flash_ev3(firmware: bytes) -> None: firmware: A firmware blob. """ - from ..connections.ev3 import EV3Bootloader + from pybricksdev.connections.ev3 import EV3Bootloader # TODO: nice error message and exit(1) if EV3 is not found with EV3Bootloader() as bootloader: diff --git a/pybricksdev/cli/lwp3/repl.py b/pybricksdev/cli/lwp3/repl.py index 64f3e30..0c3e58c 100644 --- a/pybricksdev/cli/lwp3/repl.py +++ b/pybricksdev/cli/lwp3/repl.py @@ -25,15 +25,15 @@ from prompt_toolkit.history import FileHistory from prompt_toolkit.patch_stdout import StdoutProxy, patch_stdout -from ...ble.lwp3 import ( +from pybricksdev.ble.lwp3 import ( LEGO_CID, LWP3_HUB_CHARACTERISTIC_UUID, LWP3_HUB_SERVICE_UUID, bytecodes, messages, ) -from ...ble.lwp3.bytecodes import Capabilities, HubKind, LastNetwork, Status -from ...ble.lwp3.messages import AbstractMessage, parse_message +from pybricksdev.ble.lwp3.bytecodes import Capabilities, HubKind, LastNetwork, Status +from pybricksdev.ble.lwp3.messages import AbstractMessage, parse_message logger = logging.getLogger(__name__) history_file = Path(user_cache_dir("pybricksdev"), "lwp3-explorer-history.txt") diff --git a/pybricksdev/cli/oad.py b/pybricksdev/cli/oad.py index 2123fae..c162c97 100644 --- a/pybricksdev/cli/oad.py +++ b/pybricksdev/cli/oad.py @@ -10,13 +10,18 @@ from tqdm.auto import tqdm from tqdm.contrib.logging import logging_redirect_tqdm -from ..ble.lwp3 import LEGO_CID, LWP3_HUB_SERVICE_UUID, HubKind -from ..ble.oad import OADControlPoint, OADImageBlock, OADImageIdentify, OADReturn -from ..ble.oad.control_point import ( +from pybricksdev.ble.lwp3 import LEGO_CID, LWP3_HUB_SERVICE_UUID, HubKind +from pybricksdev.ble.oad import ( + OADControlPoint, + OADImageBlock, + OADImageIdentify, + OADReturn, +) +from pybricksdev.ble.oad.control_point import ( OAD_LEGO_MARIO_DEVICE_TYPE, OAD_LEGO_TECHNIC_MOVE_DEVICE_TYPE, ) -from ..ble.oad.firmware import parse_oad_header +from pybricksdev.ble.oad.firmware import parse_oad_header __all__ = ["dump_oad_info", "flash_oad_image"] diff --git a/pybricksdev/compile.py b/pybricksdev/compile.py index 6cde349..9efdb1a 100644 --- a/pybricksdev/compile.py +++ b/pybricksdev/compile.py @@ -10,7 +10,7 @@ import mpy_cross_v5 import mpy_cross_v6 -from .tools import chunk +from pybricksdev.tools import chunk logger = logging.getLogger(__name__) diff --git a/pybricksdev/connections/ev3.py b/pybricksdev/connections/ev3.py index 52b7979..4ad3fe5 100644 --- a/pybricksdev/connections/ev3.py +++ b/pybricksdev/connections/ev3.py @@ -9,7 +9,7 @@ import hid -from ..tools import chunk +from pybricksdev.tools import chunk LEGO_VENDOR_ID = 0x0694 EV3_PRODUCT_ID = 0x0005 diff --git a/pybricksdev/connections/lego.py b/pybricksdev/connections/lego.py index 079f777..07e9e50 100644 --- a/pybricksdev/connections/lego.py +++ b/pybricksdev/connections/lego.py @@ -7,8 +7,8 @@ from serial import Serial from serial.tools import list_ports -from ..tools import chunk -from .pybricks import PybricksHub +from pybricksdev.connections.pybricks import PybricksHub +from pybricksdev.tools import chunk FILE_PACKET_SIZE = 1024 FILE_TRANSFER_SCRIPT = f""" diff --git a/pybricksdev/connections/pybricks.py b/pybricksdev/connections/pybricks.py index 1f33368..08de396 100644 --- a/pybricksdev/connections/pybricks.py +++ b/pybricksdev/connections/pybricks.py @@ -18,9 +18,9 @@ from tqdm.auto import tqdm from tqdm.contrib.logging import logging_redirect_tqdm -from ..ble.lwp3.bytecodes import HubKind -from ..ble.nus import NUS_RX_UUID, NUS_TX_UUID -from ..ble.pybricks import ( +from pybricksdev.ble.lwp3.bytecodes import HubKind +from pybricksdev.ble.nus import NUS_RX_UUID, NUS_TX_UUID +from pybricksdev.ble.pybricks import ( FW_REV_UUID, PNP_ID_UUID, PYBRICKS_COMMAND_EVENT_UUID, @@ -34,10 +34,10 @@ unpack_hub_capabilities, unpack_pnp_id, ) -from ..compile import compile_file, compile_multi_file -from ..tools import chunk -from ..tools.checksum import xor_bytes -from . import ConnectionState +from pybricksdev.compile import compile_file, compile_multi_file +from pybricksdev.connections import ConnectionState +from pybricksdev.tools import chunk +from pybricksdev.tools.checksum import xor_bytes logger = logging.getLogger(__name__) diff --git a/pybricksdev/dfu.py b/pybricksdev/dfu.py index c836c41..ac1740f 100644 --- a/pybricksdev/dfu.py +++ b/pybricksdev/dfu.py @@ -13,9 +13,9 @@ from usb.core import NoBackendError, USBError -from . import resources -from ._vendored import dfu_create, dfu_upload -from .ble.lwp3.bytecodes import HubKind +from pybricksdev import resources +from pybricksdev._vendored import dfu_create, dfu_upload +from pybricksdev.ble.lwp3.bytecodes import HubKind FIRMWARE_ADDRESS = 0x08008000 FIRMWARE_SIZE = 1 * 1024 * 1024 - 32 * 1024 # 1MiB - 32KiB diff --git a/pybricksdev/firmware.py b/pybricksdev/firmware.py index 1cd4ac6..ca79249 100644 --- a/pybricksdev/firmware.py +++ b/pybricksdev/firmware.py @@ -20,8 +20,8 @@ import semver -from .compile import compile_file, save_script -from .tools.checksum import crc32_checksum, sum_complement +from pybricksdev.compile import compile_file, save_script +from pybricksdev.tools.checksum import crc32_checksum, sum_complement class FirmwareMetadataV100( diff --git a/pybricksdev/flash.py b/pybricksdev/flash.py index 039cf3a..5371631 100644 --- a/pybricksdev/flash.py +++ b/pybricksdev/flash.py @@ -12,9 +12,9 @@ from tqdm.auto import tqdm from tqdm.contrib.logging import logging_redirect_tqdm -from .ble import BLERequestsConnection -from .ble.lwp3.bootloader import BootloaderCommand -from .ble.lwp3.bytecodes import HubKind +from pybricksdev.ble import BLERequestsConnection +from pybricksdev.ble.lwp3.bootloader import BootloaderCommand +from pybricksdev.ble.lwp3.bytecodes import HubKind logger = logging.getLogger(__name__) From a8f8b55f2e2b2e168f4da65021509f8e41741f34 Mon Sep 17 00:00:00 2001 From: David Lechner Date: Sat, 18 Jan 2025 16:28:57 -0600 Subject: [PATCH 2/8] ble.lwp3.bytecodes: Fix IODeviceCapabilities enum Fix failing on newer versions of Python which are more strict about empty enums. Fixes the following error: TypeError: has no members; specify `names=()` if you meant to create a new, empty, enum --- pybricksdev/ble/lwp3/bytecodes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pybricksdev/ble/lwp3/bytecodes.py b/pybricksdev/ble/lwp3/bytecodes.py index 0dc2f49..a1f0a87 100644 --- a/pybricksdev/ble/lwp3/bytecodes.py +++ b/pybricksdev/ble/lwp3/bytecodes.py @@ -1008,7 +1008,7 @@ class IODeviceCapabilities(IntFlag): Sensor capabilities flags. (48-bit) """ - pass + names = () class DataFormat(IntEnum): From a0a971b9f00395ac014eacbbf24bc10b18cfc091 Mon Sep 17 00:00:00 2001 From: David Lechner Date: Sat, 18 Jan 2025 16:34:33 -0600 Subject: [PATCH 3/8] ble.lwp3.bytecodes: Replace workaround with proper fix The recommended way to handle this is to have an empty names attribute rather than having a fake member. --- pybricksdev/ble/lwp3/bytecodes.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/pybricksdev/ble/lwp3/bytecodes.py b/pybricksdev/ble/lwp3/bytecodes.py index a1f0a87..f1c0ee2 100644 --- a/pybricksdev/ble/lwp3/bytecodes.py +++ b/pybricksdev/ble/lwp3/bytecodes.py @@ -574,8 +574,7 @@ class PortID(IntEnum): All enum members are dynamic. (0 to 49 are external and 50 - 100 are internal) """ - # not used - Python requires at least one member - _PLACEHOLDER = -1 + names = () @property def internal(self) -> bool: @@ -914,8 +913,7 @@ class HwNetExtFamily(IntEnum): a single byte. """ - # not used - Python requires at least one member - _PLACEHOLDER = -1 + names = () @property def family(self) -> HwNetFamily: From e1e0f8d046d24ec0bb574ae0c359b62259e596ed Mon Sep 17 00:00:00 2001 From: David Lechner Date: Sat, 18 Jan 2025 16:35:58 -0600 Subject: [PATCH 4/8] test.ble: fix tests for changes in enum repr in Python 3.12 It appears that Python has changed how repr works for enums in some cases. This fixes tests that were failing on Python 3.12. --- tests/ble/test_lwp3_messages.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/ble/test_lwp3_messages.py b/tests/ble/test_lwp3_messages.py index 945712e..da0a2c8 100644 --- a/tests/ble/test_lwp3_messages.py +++ b/tests/ble/test_lwp3_messages.py @@ -945,6 +945,8 @@ def test_constructor(self): assert ( repr(msg) == "PortInfoModeInfoMessage(, , 5, [0, 1, 2], [3, 4])" + or repr(msg) + == "PortInfoModeInfoMessage(, , 5, [0, 1, 2], [3, 4])" ) def test_parse_message(self): @@ -1174,6 +1176,8 @@ def test_constructor(self): assert ( repr(msg) == "PortModeInfoCapabilitiesMessage(, 2, )" + or repr(msg) + == "PortModeInfoCapabilitiesMessage(, 2, )" ) def test_parse_message(self): From c568ba17f5a44b4ece01bf9dec7adb452c823d6b Mon Sep 17 00:00:00 2001 From: David Lechner Date: Sat, 18 Jan 2025 16:39:54 -0600 Subject: [PATCH 5/8] compile: separate project directory and file path in compile_file() mpy-cross saves the file path as part of the binary file. To keep things small and not leak host computer details, we want to only include the portion of the path that is relative to the project directory. Previously, this could only be done by changing the current working directory to the project directory before calling compile_file(). Now, that is no longer necessary and the project directory is passed as a separate argument. This fixes not being able to compile files piped from stdin when using the cli tool. --- CHANGELOG.md | 3 +++ pybricksdev/cli/flash.py | 5 ++++- pybricksdev/compile.py | 26 ++++++++++++++++---------- pybricksdev/connections/pybricks.py | 4 +++- pybricksdev/firmware.py | 4 +++- tests/test_compile.py | 4 +++- 6 files changed, 32 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7fb937a..52814f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Fixed +- Fix crash when running `pybricksdev run ble -` (bug introduced in alpha.49). + ## [1.0.0-alpha.52] - 2024-11-29 ### Added diff --git a/pybricksdev/cli/flash.py b/pybricksdev/cli/flash.py index d10919c..7566ba7 100644 --- a/pybricksdev/cli/flash.py +++ b/pybricksdev/cli/flash.py @@ -5,6 +5,7 @@ import hashlib import json import logging +import os import struct import sys import zipfile @@ -117,7 +118,9 @@ async def download_and_run(client: BleakClient, script: str, abi: int) -> None: # file has to be closed so mpy-cross can open it temp.file.close() - mpy = await compile_file(temp.name, abi) + mpy = await compile_file( + os.path.dirname(temp.name), os.path.basename(temp.name), abi + ) recv_queue = asyncio.Queue() diff --git a/pybricksdev/compile.py b/pybricksdev/compile.py index 9efdb1a..c37dfb0 100644 --- a/pybricksdev/compile.py +++ b/pybricksdev/compile.py @@ -29,12 +29,17 @@ def make_build_dir(): raise FileExistsError("A file named build already exists.") -async def compile_file(path: str, abi: int, compile_args: Optional[List[str]] = None): +async def compile_file( + proj_dir: str, proj_path: str, abi: int, compile_args: Optional[List[str]] = None +): """Compiles a Python file with ``mpy-cross``. Arguments: - path: - Path to script that is to be compiled. + proj_dir: + Path to project containing the script to be compiled + proj_path: + Path to script that is to be compiled relative to proj_dir. This is + the portion of the name that is passed to ``mpy-cross``. abi: Expected MPY ABI version. compile_args: @@ -50,7 +55,7 @@ async def compile_file(path: str, abi: int, compile_args: Optional[List[str]] = """ # Get version info - with open(path, "r") as f: + with open(os.path.join(proj_dir, proj_path), "r") as f: loop = asyncio.get_running_loop() script = f.read() @@ -58,14 +63,14 @@ async def compile_file(path: str, abi: int, compile_args: Optional[List[str]] = proc, mpy = await loop.run_in_executor( None, lambda: mpy_cross_v5.mpy_cross_compile( - path, script, no_unicode=True, extra_args=compile_args + proj_path, script, no_unicode=True, extra_args=compile_args ), ) elif abi == 6: proc, mpy = await loop.run_in_executor( None, lambda: mpy_cross_v6.mpy_cross_compile( - path, script, extra_args=compile_args + proj_path, script, extra_args=compile_args ), ) else: @@ -114,7 +119,8 @@ async def compile_multi_file(path: str, abi: Union[int, Tuple[int, int]]): """ # compile files using Python to find imports contained within the same directory as path - search_path = [os.path.dirname(path)] + proj_path = os.path.dirname(path) + search_path = [proj_path] finder = ModuleFinder(search_path) try: @@ -136,9 +142,9 @@ async def compile_multi_file(path: str, abi: Union[int, Tuple[int, int]]): if not module.__file__: continue - relative_file = os.path.relpath(module.__file__, os.path.dirname(path)) - - mpy = await compile_file(relative_file, abi_major) + mpy = await compile_file( + proj_path, os.path.relpath(module.__file__, proj_path), abi_major + ) parts.append(len(mpy).to_bytes(4, "little")) parts.append(name.encode() + b"\x00") diff --git a/pybricksdev/connections/pybricks.py b/pybricksdev/connections/pybricks.py index 08de396..0f61a88 100644 --- a/pybricksdev/connections/pybricks.py +++ b/pybricksdev/connections/pybricks.py @@ -582,7 +582,9 @@ async def _legacy_run(self, py_path: str, wait: bool) -> None: Version of :meth:`run` for compatibility with older firmware () """ # Compile the script to mpy format - mpy = await compile_file(py_path, self._mpy_abi_version) + mpy = await compile_file( + os.path.dirname(py_path), os.path.basename(py_path), self._mpy_abi_version + ) try: self._downloading_via_nus = True diff --git a/pybricksdev/firmware.py b/pybricksdev/firmware.py index ca79249..8a77979 100644 --- a/pybricksdev/firmware.py +++ b/pybricksdev/firmware.py @@ -133,9 +133,11 @@ async def _create_firmware_v1( if "main.py" in archive.namelist(): main_py = io.TextIOWrapper(archive.open("main.py")) + main_py_path = save_script(main_py.read()) mpy = await compile_file( - save_script(main_py.read()), + os.path.dirname(main_py_path), + os.path.basename(main_py_path), metadata["mpy-abi-version"], metadata["mpy-cross-options"], ) diff --git a/tests/test_compile.py b/tests/test_compile.py index 2274201..7b817f4 100644 --- a/tests/test_compile.py +++ b/tests/test_compile.py @@ -19,7 +19,9 @@ async def test_compile_file(abi: int): f.write("print('test')") f.close() - mpy = await compile_file(f.name, abi=abi) + mpy = await compile_file( + os.path.dirname(f.name), os.path.basename(f.name), abi=abi + ) magic, abi_ver, flags, int_bits = struct.unpack_from(" Date: Sat, 18 Jan 2025 16:51:01 -0600 Subject: [PATCH 6/8] poetry: update asyncssh Fix warnings about moved imports in cryptography dependency. --- poetry.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/poetry.lock b/poetry.lock index 734b414..dc54937 100644 --- a/poetry.lock +++ b/poetry.lock @@ -189,18 +189,18 @@ files = [ [[package]] name = "asyncssh" -version = "2.14.2" +version = "2.19.0" description = "AsyncSSH: Asynchronous SSHv2 client and server library" optional = false -python-versions = ">= 3.6" +python-versions = ">=3.6" files = [ - {file = "asyncssh-2.14.2-py3-none-any.whl", hash = "sha256:6ff9923389a16bda4f681c1fc253386cc4e1f19fb74fd0684dd0d31943ebe5e4"}, - {file = "asyncssh-2.14.2.tar.gz", hash = "sha256:e956bf8988d07a06ba3305f6604e261f4ca014c4a232f0873f1c7692fbe3cfc2"}, + {file = "asyncssh-2.19.0-py3-none-any.whl", hash = "sha256:bb82ac30ff0cb4393fbaf1114e606ad7a4f13d6c4bdaed423c033ee26b455228"}, + {file = "asyncssh-2.19.0.tar.gz", hash = "sha256:723dead4d068b558708dc66a4ca7e7a93a813aa9416036eccb9af4c03ae2cf30"}, ] [package.dependencies] cryptography = ">=39.0" -typing-extensions = ">=3.6" +typing_extensions = ">=4.0.0" [package.extras] bcrypt = ["bcrypt (>=3.1.3)"] From 0fa505326f5a1849c005642d71368f17492a60fd Mon Sep 17 00:00:00 2001 From: David Lechner Date: Sat, 18 Jan 2025 16:54:30 -0600 Subject: [PATCH 7/8] poetry: update hidapi Fix failing on Python 3.13. --- poetry.lock | 150 ++++++++++++++++++++++++++++------------------------ 1 file changed, 80 insertions(+), 70 deletions(-) diff --git a/poetry.lock b/poetry.lock index dc54937..e36317f 100644 --- a/poetry.lock +++ b/poetry.lock @@ -861,80 +861,90 @@ files = [ [[package]] name = "hidapi" -version = "0.14.0" +version = "0.14.0.post4" description = "A Cython interface to the hidapi from https://github.com/libusb/hidapi" optional = false python-versions = "*" files = [ - {file = "hidapi-0.14.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f68bbf88805553911e7e5a9b91136c96a54042b6e3d82d39d733d2edb46ff9a6"}, - {file = "hidapi-0.14.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b264c6a1a1a0cacacc82299785415bec91184cb3e4a77d127c40016086705327"}, - {file = "hidapi-0.14.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:01929fbbe206ebcb0bad9b8e925e16de0aa8f872bf80a263f599e519866d9900"}, - {file = "hidapi-0.14.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1b4052f17321f5f0b641e020eae87db5bb0103f893198e61b2495358db83ddab"}, - {file = "hidapi-0.14.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:349976417f7f3371c7133a6427ed8f4faa06fbd93e9b5309d86689f25f191150"}, - {file = "hidapi-0.14.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e7ff737cbb4adf238aa0da50e8b5c2f083e8f62b3c5132fbd732ba59918a909c"}, - {file = "hidapi-0.14.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:5b960bcf8c41bd861554adc5932d1d7e0ed169315ca87dbd4d23ec8337764247"}, - {file = "hidapi-0.14.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:3b8af9ef71b7149e85f2118eaac9fd7e7ea95528029a66f351d0049877d5a179"}, - {file = "hidapi-0.14.0-cp310-cp310-win32.whl", hash = "sha256:7ef0f40a02e0b56fe2e7c93dfc9810245f2feeaa0c2ea76654d0768722883639"}, - {file = "hidapi-0.14.0-cp310-cp310-win_amd64.whl", hash = "sha256:9fdc08eb19f2fffb989124d1dbea3aa62dd0036615bbf464ceafee0353673bf4"}, - {file = "hidapi-0.14.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4046bbfc67c5587ca638b875858569a8787e6955eff5dea4e424044de09fe7e4"}, - {file = "hidapi-0.14.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:15f1fd34b0719d1e4d1bbc0bce325b318ee3e85c36fac0d23c6fb9d7f4d611db"}, - {file = "hidapi-0.14.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c0959d89bc95acb4f9e6d58c8562281e22694959e42c10108193a1362b4fcd9"}, - {file = "hidapi-0.14.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c1b1ded4a823cc5c2075a622b48d02bc0a72f57579ea24c956ef29649a49eb66"}, - {file = "hidapi-0.14.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2906ad143ec40009c33348ab4b3f7a9bdaa87b65bdc55983399bed47ee90a818"}, - {file = "hidapi-0.14.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e1927fc5f7099b98529a4cefe8e0cd92ffb026abf5c449310d1d359433c5d94a"}, - {file = "hidapi-0.14.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:76041e2e5d52c864bc4a381f082edeb89e85829130d1fef3366f320237da0580"}, - {file = "hidapi-0.14.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:93d7814aa1c7e0f1cce300b3b63828abecb024da72e9a10d46db811cf466e68e"}, - {file = "hidapi-0.14.0-cp311-cp311-win32.whl", hash = "sha256:651c2382e974e866d78334cdde3c290a04fcbab4cec940c0d3586d77d11b9566"}, - {file = "hidapi-0.14.0-cp311-cp311-win_amd64.whl", hash = "sha256:de293e7291b1ec813a97e42625c2c0a41b0d25d495b3dc5864bbb3dbbb5a719d"}, - {file = "hidapi-0.14.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:fc9ec2321bf3b0b4953910aa87c0c8ab5f93b1f113a9d3d4f18845ce54708d13"}, - {file = "hidapi-0.14.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a68820a5de54a54d145d88f31c74257965bd03ae454263eda054f02bf34dcc9c"}, - {file = "hidapi-0.14.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:86752ca0db00e5a5e991ebc5854400ff16d3812d6d9a156fea4de7d5f10ba801"}, - {file = "hidapi-0.14.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4b65cc159fcf1839d078d3de196146626c1a865bd9136fda5fa490f689e904c9"}, - {file = "hidapi-0.14.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ab1b1dc8b915a0faa7b976ed8291142cf93c2acecf533db8c748fc64be1a004"}, - {file = "hidapi-0.14.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:418de0a2ec786d610967984fe5d6cb9584413dcce8b9fdd23fff998596f80a95"}, - {file = "hidapi-0.14.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:1a777912e93a9f773aa6359fdb7b152b654991bb9afd6d3ce20e52dfbf18db00"}, - {file = "hidapi-0.14.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:33098ba2f10f704a85b62720becf444a19753d3a1ee4b8dda7dc289c1d6eda9b"}, - {file = "hidapi-0.14.0-cp312-cp312-win32.whl", hash = "sha256:5e3318f0e66c4d46977fc8ba73a2ad33c2de367d133b70b243051283d0ecdaca"}, - {file = "hidapi-0.14.0-cp312-cp312-win_amd64.whl", hash = "sha256:b4f3a4e41886a19dcb9ea872a6f75ef42baba124a150b5b0a03379da174e1f70"}, - {file = "hidapi-0.14.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:1370bc6a364fd292accd580a8d7bac4219932144d149f3a513bb472581eac421"}, - {file = "hidapi-0.14.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e6ef0bdc69310cfdff83faf96c75492ac3d8cf355af275904f1dd90a3c5f24a4"}, - {file = "hidapi-0.14.0-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9e245719a5ede83c779dd99a4553002ae684d92d0f3e4274dcf06882b063f127"}, - {file = "hidapi-0.14.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:833a32c3e44780f37d46dffd559b8e245034c92ae25060f752e4f34e9c7efe24"}, - {file = "hidapi-0.14.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:103dfa1c19832b8928775ec491c3016c9f9063dd2ccdc37811bf12f3cc0a789f"}, - {file = "hidapi-0.14.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:78b176bc64a8908b37d5f34b3cce30158c1ebeaf1208c3b5ed62ad456fa1277d"}, - {file = "hidapi-0.14.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:1a63c0bc33329d0e572afe20b9dff27155d4fff34d0f2fa662e6704b9e2e18c4"}, - {file = "hidapi-0.14.0-cp36-cp36m-win32.whl", hash = "sha256:365d7c9fdcae71ae41797dc2dd062dfed4362d1b36d21fa62afbc16c5ec3cd5a"}, - {file = "hidapi-0.14.0-cp36-cp36m-win_amd64.whl", hash = "sha256:810ad22831e4a150c2d6f27141fcf2826fd085ccacf4262d5c742c90aa81cd54"}, - {file = "hidapi-0.14.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3ed9f993a6f8a611c11ef213968c6972e17d7e8b27936349884c475dc0309e71"}, - {file = "hidapi-0.14.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0fb47a0a8c3a6797306ea9eb8d1bdad68e5493ef5c8fa2e644501d56f2677551"}, - {file = "hidapi-0.14.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b4513311fad7e499ebb0d7a26178557b85044983199a280cb95c2038902fe1a0"}, - {file = "hidapi-0.14.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dff930adb37d1bcaeca3cf0dcec00eb72c109aa42c84858809cbae2972d79661"}, - {file = "hidapi-0.14.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:cc654cd37d04bbb782c39901bf872b2af5d3c3ead2b1a23b084a81e469b6d0a7"}, - {file = "hidapi-0.14.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:de5af3941f31cfb044a87fc9d9b2f80b3b71b58b27481d9877061b76e9625a22"}, - {file = "hidapi-0.14.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e5f01e21648a58de56c24a093e4901fca039b9658074b413c2a4ceb16ea6473b"}, - {file = "hidapi-0.14.0-cp37-cp37m-win32.whl", hash = "sha256:60c034ec3ef3e5679232d9e6c003c4848e4772032d683f0b91ddb84b87d8698d"}, - {file = "hidapi-0.14.0-cp37-cp37m-win_amd64.whl", hash = "sha256:c8bba64d6ed49fa7ea4f4515986450223f5c744be448c846fb0614bc53b536bd"}, - {file = "hidapi-0.14.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:48e2cf77626f3cfdda9624de3be7f9c55e37efbb39882d2e96a92d38893a09cb"}, - {file = "hidapi-0.14.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a6edc57962a9f30bff73fc0cc80915c9da9ab3e0892c601263198f8d21d8dfff"}, - {file = "hidapi-0.14.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e822e899c13eb1e3a575712d7be5bd03a9103f6027b00ab4351c8404cec5719d"}, - {file = "hidapi-0.14.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bb87cf8f23c15346bc1487e6f39d11b37d3ff7788037d3760b7907ea325b6d2c"}, - {file = "hidapi-0.14.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:93697007df8ba38ab3ae3e777a6875cd1775fc720afe27e4c624cecbab7720de"}, - {file = "hidapi-0.14.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:832a2d2d8509d98381f0bf09b4e1f897765a9c8e0a72164174bcbf983d7d69a3"}, - {file = "hidapi-0.14.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:6c000635c14f11ee3633530ef2d56de1ef266dc89b98f0a5f21e08ab8a9b151b"}, - {file = "hidapi-0.14.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:174be08584e5c686fb02a6f51cc159d6e491fd7a7c7d1978b28f913362c7ad11"}, - {file = "hidapi-0.14.0-cp38-cp38-win32.whl", hash = "sha256:b054abf40b5aa7122314af59d0244fa274a50c4276d20695d8b7ff69564beb95"}, - {file = "hidapi-0.14.0-cp38-cp38-win_amd64.whl", hash = "sha256:f575381efa788e1a894c68439644817b152b8a68ead643e42c23ba28eeedc33b"}, - {file = "hidapi-0.14.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5299d74d96bdc9eaa83496c972048db0027d012a08440b33bdb6dd10a7491da9"}, - {file = "hidapi-0.14.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4c78ff5c46128bdf68b2c4e4b08fac7765ef79f6ee7e17c8a2f7d3090a591d97"}, - {file = "hidapi-0.14.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e635c037d28e1ceded2043d81b879d81348a278d1ae668954a5a7a7d383f7d7"}, - {file = "hidapi-0.14.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c1425f523258d25d8f32a6493978532477c4d7507f5f9252417b1d629427871e"}, - {file = "hidapi-0.14.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:96ecea60915212e59940db41c2a91709ebd4ec6a04e03b0db37a4ddb6825bee6"}, - {file = "hidapi-0.14.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:537fc17d59e1de48c1832d5bda60d63f56bcb1300cce7e382d45b8ef3bcacd53"}, - {file = "hidapi-0.14.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:e43f2db347b7faf3fcefb6c39f45615d1d6f58db7305d4474bb63b2845ed4fc8"}, - {file = "hidapi-0.14.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:fb4e94e45f6dddb20d59501187721e5d3b02e6cc8a59d261dd5cac739008582a"}, - {file = "hidapi-0.14.0-cp39-cp39-win32.whl", hash = "sha256:b4a0feac62d80eca36e2c8035fe4f57c440fbfcd9273a909112cb5bd9baae449"}, - {file = "hidapi-0.14.0-cp39-cp39-win_amd64.whl", hash = "sha256:ed112c9ba0adf41d7e04bf5389dc150ada4d94a6ef1cb56c325d5aed1e4e07d2"}, - {file = "hidapi-0.14.0.tar.gz", hash = "sha256:a7cb029286ced5426a381286526d9501846409701a29c2538615c3d1a612b8be"}, + {file = "hidapi-0.14.0.post4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:01747e681d138ec614321ef6f069e5be3743fa210112e529a34d3e99635e4ac0"}, + {file = "hidapi-0.14.0.post4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e20d0a1298a4bd342d7d927d928f1a5a29e5fc9dbf9a79e95dc6e2d386d5070"}, + {file = "hidapi-0.14.0.post4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f0cc21e82e95cb92ef951df8eb8acf5626ac8fa14ab5292abdab1b2349970445"}, + {file = "hidapi-0.14.0.post4-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cb1a2b5da0dcfab6837281342d1785cc373484bd3f27bd06fd2211d88075a7bd"}, + {file = "hidapi-0.14.0.post4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e11d475429a1bc943ceac4ad8da4be63b240e00da5e10863fc3cbd9a35fdb51c"}, + {file = "hidapi-0.14.0.post4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:2d1c102f754b2085b270e7c29cb8a148ffb05e10325c373d05ac16e2cbce131c"}, + {file = "hidapi-0.14.0.post4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:7d099c259aadcab2bc3f4fb5a1db579ec886c2cade7533016f62778235150746"}, + {file = "hidapi-0.14.0.post4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:80fa94668d21b12daf62b034f647d71236470a8ba9a7580e220c47e9c119d932"}, + {file = "hidapi-0.14.0.post4-cp310-cp310-win32.whl", hash = "sha256:21ebd1420db116733536fae227f1cb30ad74bded5090269cdda4facfa73a8867"}, + {file = "hidapi-0.14.0.post4-cp310-cp310-win_amd64.whl", hash = "sha256:a90cfdd29c10425cd4e4cff34adb12d25048561fc946f3562679e45721060a1c"}, + {file = "hidapi-0.14.0.post4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:74ae8ce339655b2568d74e49c8ef644d34a445dd0a9b4b89d1bf09447b83f5af"}, + {file = "hidapi-0.14.0.post4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e749b79d9cafc1e9fd9d397d8039377c928ca10a36847fda6407169513802f68"}, + {file = "hidapi-0.14.0.post4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4169893fe5e368777fce7575a8bdedc1861f13d8fb9fda6b05e8155dde6eb7f1"}, + {file = "hidapi-0.14.0.post4-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0d51f8102a2441ce22e080576f8f370d25cb3962161818a89f236b0401840f18"}, + {file = "hidapi-0.14.0.post4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ff021ed0962f2d5d67405ae53c85f6cb3ab8c5af3dff7db8c74672f79f7a39d1"}, + {file = "hidapi-0.14.0.post4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8ab5ba9fce95e342335ef48640221a46600c1afb66847432fad9823d40a2022"}, + {file = "hidapi-0.14.0.post4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:56d7538a4e156041bb80f07f47c327f8944e39da469b010041ce44e324d0657c"}, + {file = "hidapi-0.14.0.post4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a28de4a03fc276614518d8d0997d8152d0edaf8ca9166522316ef1c455e8bc29"}, + {file = "hidapi-0.14.0.post4-cp311-cp311-win32.whl", hash = "sha256:348e68e3a2145a6ec6bebce13ffdf3e5883d8c720752c365027f16e16764def6"}, + {file = "hidapi-0.14.0.post4-cp311-cp311-win_amd64.whl", hash = "sha256:5a5af70dad759b45536a9946d8232ef7d90859845d3554c93bea3e790250df75"}, + {file = "hidapi-0.14.0.post4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:129d684c2760fafee9014ce63a58d8e2699cdf00cd1a11bb3d706d4715f5ff96"}, + {file = "hidapi-0.14.0.post4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4f04de00e40db2efc0bcdd047c160274ba7ccd861100fd87c295dd63cb932f2f"}, + {file = "hidapi-0.14.0.post4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:10a01af155c51a8089fe44e627af2fbd323cfbef7bd55a86837d971aef6088b0"}, + {file = "hidapi-0.14.0.post4-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6eaff1d120c47e1a121eada8dc85eac007d1ed81f3db7fc0da5b6ed17d8edefb"}, + {file = "hidapi-0.14.0.post4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fedb9c3be6a2376de436d13fcb37a686a9b6bc988585bcc4f5ec61cad925e794"}, + {file = "hidapi-0.14.0.post4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6270677da02e86b56b81afd5f6f313736b8315b493f3c8a431da285e3a3c5de9"}, + {file = "hidapi-0.14.0.post4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:da700db947562f8c0ac530215b74b5a27e4c669916ec99cfb5accd14ba08562c"}, + {file = "hidapi-0.14.0.post4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:707b1ebf5cb051b020e94b039e603351bf2e6620b48fc970228e0dd5d3a91fca"}, + {file = "hidapi-0.14.0.post4-cp312-cp312-win32.whl", hash = "sha256:1487312ad50cf2c08a5ea786167b3229afd6478c4b26974157c3845a84e91231"}, + {file = "hidapi-0.14.0.post4-cp312-cp312-win_amd64.whl", hash = "sha256:8d924bd002a1c17ca51905b3b7b3d580e80ec211a9b8fe4667b73db0ff9e9b54"}, + {file = "hidapi-0.14.0.post4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:6f96ae777e906f0a9d6f75e873313145dfec2b774f558bfcae8ba34f09792460"}, + {file = "hidapi-0.14.0.post4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6439fc9686518d0336fac8c5e370093279f53c997540065fce131c97567118d8"}, + {file = "hidapi-0.14.0.post4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2acadb4f1ae569c4f73ddb461af8733e8f5efcb290c3d0ef1b0671ba793b0ae3"}, + {file = "hidapi-0.14.0.post4-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:884fa003d899113e14908bd3b519c60b48fc3cec0410264dcbdad1c4a8fc2e8d"}, + {file = "hidapi-0.14.0.post4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8a2d466b995f8ff387d68c052d3b74ee981a4ddc4f1a99f32f2dc7022273dc11"}, + {file = "hidapi-0.14.0.post4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e1f6409854c0a8ed4d1fdbe88d5ee4baf6f19996d1561f76889a132cb083574d"}, + {file = "hidapi-0.14.0.post4-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:bca568a2b7d0d454c7921d70b1cc44f427eb6f95961b6d7b3b9b4532d0de74ef"}, + {file = "hidapi-0.14.0.post4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9f14ac2737fd6f58d88d2e6bf8ebd03aac7b486c14d3f570b7b1d0013d61b726"}, + {file = "hidapi-0.14.0.post4-cp313-cp313-win32.whl", hash = "sha256:b6b9c4dbf7d7e2635ff129ce6ea82174865c073b75888b8b97dda5a3d9a70493"}, + {file = "hidapi-0.14.0.post4-cp313-cp313-win_amd64.whl", hash = "sha256:87218eeba366c871adcc273407aacbabab781d6a964919712d5583eded5ca50f"}, + {file = "hidapi-0.14.0.post4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:e9af3c9191b7a4dade9152454001622519f4ecfa674b78929b739cfbf4b35d51"}, + {file = "hidapi-0.14.0.post4-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a2c4c3b3d77b759a4a118aa8428da1daf21c01b49915f44d7a3f198bcee4aa7b"}, + {file = "hidapi-0.14.0.post4-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5c14c54cbfd45553cd3e6a23014f8e8f2d12c41cd2783e84c2cb774976d4648f"}, + {file = "hidapi-0.14.0.post4-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:04357092b39631d8034b17fd111c5583be2790ad7979ac1983173344d28824e7"}, + {file = "hidapi-0.14.0.post4-cp36-cp36m-musllinux_1_2_aarch64.whl", hash = "sha256:949f437f517e81bc567429f41fb1e67349046eb43e52d47b2852b5847de452ee"}, + {file = "hidapi-0.14.0.post4-cp36-cp36m-musllinux_1_2_i686.whl", hash = "sha256:f787b76288450f60250895597dabb080894f0ea09ad5df0433412fee42452435"}, + {file = "hidapi-0.14.0.post4-cp36-cp36m-musllinux_1_2_x86_64.whl", hash = "sha256:41d532d5a358a63db4d7fc1e57ea107150445c90167b39ba6f8fb84597396a48"}, + {file = "hidapi-0.14.0.post4-cp36-cp36m-win32.whl", hash = "sha256:3253d198b193065d633cde3f9a59dabeeb1608ece26f0f319a151e8c7775d7ae"}, + {file = "hidapi-0.14.0.post4-cp36-cp36m-win_amd64.whl", hash = "sha256:1bee0f731874d78367a3bf131cb0325578bc9fee0678ed00c4ca3ded45d11c20"}, + {file = "hidapi-0.14.0.post4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:1807ff8abe3c5dcfa9d8acd71b1ab9f0aeb69cdbb039ddcbb150ed9fbbfd1ba7"}, + {file = "hidapi-0.14.0.post4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4939faf6382d1c89462e72aa08636bbfe97ecb5464a34b14997e0ca3e1f92906"}, + {file = "hidapi-0.14.0.post4-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ac3e6e794a0fd6ee4634bf1beea1c3c91ab6faf8b16f3f672a42541f9c5ea41f"}, + {file = "hidapi-0.14.0.post4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c45a493dffdfe614a9943a8c7f0df617254f836f1242478f7780fbeafb18a131"}, + {file = "hidapi-0.14.0.post4-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:142374bb39c8973c6d04a2b8b767d64891741d05b09364b32531d9389c3a15bb"}, + {file = "hidapi-0.14.0.post4-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:da777638f5ecf9ef6c979f6c793417f54104d56ac99a48312d6f7e47858c2dd8"}, + {file = "hidapi-0.14.0.post4-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:20a466e4cf2230687d21f55ffffb1a2384a2262fc343e507dd01d1ab981f7573"}, + {file = "hidapi-0.14.0.post4-cp37-cp37m-win32.whl", hash = "sha256:ff67139fbaa91eed55e7e916bdc1ccdaf8c909a80a9c480011caa65c4ba82a97"}, + {file = "hidapi-0.14.0.post4-cp37-cp37m-win_amd64.whl", hash = "sha256:1304fdeb694f581c46e7b0d6aebc6adfa66219177f04cacddbec0bd906bd5b7c"}, + {file = "hidapi-0.14.0.post4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9e4b462fc1f2b160442618448132aebadb71c06b6eb7654eae4385c490100a67"}, + {file = "hidapi-0.14.0.post4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:68d7e9ba5c48e50f322057b9f88d799c105b5d46c966981aa8e5047b6091541f"}, + {file = "hidapi-0.14.0.post4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:293b207e737df4577d27661c5135e7c16976f706d3739d7a53a169dde1aaebaa"}, + {file = "hidapi-0.14.0.post4-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a18af6ebd751eea7ddfb093ddf7d0371b05ba0f9a2f8593c7255a34e6bd753ff"}, + {file = "hidapi-0.14.0.post4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:380a74e743afe7a0241e0efce73ce9697f41d4e2e0a030be5458a44f9119427a"}, + {file = "hidapi-0.14.0.post4-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:6e08884ee9e1e3963701c1cdf22edd17c7ff708728f163efc396964460b3f9b4"}, + {file = "hidapi-0.14.0.post4-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:fbd2835ff193d0261e0de375fea006cb7cb18a30ae1657af48a43e381f6a0995"}, + {file = "hidapi-0.14.0.post4-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:6b424ec16068d58d13fb67c7fb728824a3888f8f7fb6ffa3c82d5a54d8b74b7f"}, + {file = "hidapi-0.14.0.post4-cp38-cp38-win32.whl", hash = "sha256:8de94caca7f2616e41466c0ccdf7a96f567914e9e85e89e0b607018777fc0755"}, + {file = "hidapi-0.14.0.post4-cp38-cp38-win_amd64.whl", hash = "sha256:1591e98c0e6db4cc1e34e96295b4ea68eaf37d365d664570441388869e8e3618"}, + {file = "hidapi-0.14.0.post4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:58a0a0c029886de8b301ce1ee2e7fd6914ae1ca49feb37cc9930c26baa683427"}, + {file = "hidapi-0.14.0.post4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e70eab52781e58e819730d99e3c825e92c15ec2138b6902ed078c8cd73317ce0"}, + {file = "hidapi-0.14.0.post4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:97192b7756dd854cb2ebc8a1862ffa009cdc203e0399777764462cae3c459d58"}, + {file = "hidapi-0.14.0.post4-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f27c74deda0282a97dd0f006fd79d6d08fdb16c7a3ba156d52fce85e48515b0a"}, + {file = "hidapi-0.14.0.post4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c8f722864a03c1d243a9538f0872e233d07fc3fe1d945c66c0cb632060d6d009"}, + {file = "hidapi-0.14.0.post4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f67e60eaa287e0fa35223f2d1f9afda81dd7312c7ba07e08fbdaf1af8a923530"}, + {file = "hidapi-0.14.0.post4-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:fa66391be8acb358b381c30f32be5880d591a3358e531d980832d593dfe83d5a"}, + {file = "hidapi-0.14.0.post4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f3ce310d366335e1ac9416d8e4a27d6eef2ae896fbee0135484d39d001711bea"}, + {file = "hidapi-0.14.0.post4-cp39-cp39-win32.whl", hash = "sha256:60115947607b8b0a719420726a541bad68728ece38b20654e81fef77c9e0bd2f"}, + {file = "hidapi-0.14.0.post4-cp39-cp39-win_amd64.whl", hash = "sha256:21627bb8a0e2023da1dfb7cb7b970c30d6a86e6498721f1123d018b2f64b426f"}, + {file = "hidapi-0.14.0.post4.tar.gz", hash = "sha256:48fce253e526d17b663fbf9989c71c7ef7653ced5f4be65f1437c313fb3dbdf6"}, ] [package.dependencies] From 8b0cccf92edfab4747ab631271916a1afbb3aac3 Mon Sep 17 00:00:00 2001 From: David Lechner Date: Sat, 18 Jan 2025 17:26:23 -0600 Subject: [PATCH 8/8] usb: consolidate USB VID/PID definitions These were scattered about and repeated or hard-coded in various places. --- pybricksdev/connections/ev3.py | 9 ++------- pybricksdev/connections/lego.py | 6 +++++- pybricksdev/dfu.py | 25 ++++++++++++++----------- pybricksdev/usb/__init__.py | 10 ++++++++++ pyproject.toml | 1 + 5 files changed, 32 insertions(+), 19 deletions(-) create mode 100644 pybricksdev/usb/__init__.py diff --git a/pybricksdev/connections/ev3.py b/pybricksdev/connections/ev3.py index 4ad3fe5..b5a3573 100644 --- a/pybricksdev/connections/ev3.py +++ b/pybricksdev/connections/ev3.py @@ -10,10 +10,7 @@ import hid from pybricksdev.tools import chunk - -LEGO_VENDOR_ID = 0x0694 -EV3_PRODUCT_ID = 0x0005 -EV3_BOOTLOADER_PRODUCT_ID = 0x0006 +from pybricksdev.usb import EV3_BOOTLOADER_USB_PID, LEGO_USB_VID class MessageType(enum.IntEnum): @@ -70,9 +67,7 @@ def open(self) -> None: """ Opens an HID connection to the EV3 bootloader. """ - self._device.open( - vendor_id=LEGO_VENDOR_ID, product_id=EV3_BOOTLOADER_PRODUCT_ID - ) + self._device.open(vendor_id=LEGO_USB_VID, product_id=EV3_BOOTLOADER_USB_PID) def close(self) -> None: """ diff --git a/pybricksdev/connections/lego.py b/pybricksdev/connections/lego.py index 07e9e50..5091aaf 100644 --- a/pybricksdev/connections/lego.py +++ b/pybricksdev/connections/lego.py @@ -9,6 +9,7 @@ from pybricksdev.connections.pybricks import PybricksHub from pybricksdev.tools import chunk +from pybricksdev.usb import LEGO_USB_VID FILE_PACKET_SIZE = 1024 FILE_TRANSFER_SCRIPT = f""" @@ -77,7 +78,10 @@ async def connect(self, device=None): port = None devices = list_ports.comports() for dev in devices: - if dev.product == "LEGO Technic Large Hub in FS Mode" or dev.vid == 0x0694: + if ( + dev.product == "LEGO Technic Large Hub in FS Mode" + or dev.vid == LEGO_USB_VID + ): port = dev.device break diff --git a/pybricksdev/dfu.py b/pybricksdev/dfu.py index ac1740f..a6265ab 100644 --- a/pybricksdev/dfu.py +++ b/pybricksdev/dfu.py @@ -16,20 +16,23 @@ from pybricksdev import resources from pybricksdev._vendored import dfu_create, dfu_upload from pybricksdev.ble.lwp3.bytecodes import HubKind +from pybricksdev.usb import ( + LEGO_USB_VID, + MINDSTORMS_INVENTOR_DFU_USB_PID, + SPIKE_ESSENTIAL_DFU_USB_PID, + SPIKE_PRIME_DFU_USB_PID, +) FIRMWARE_ADDRESS = 0x08008000 FIRMWARE_SIZE = 1 * 1024 * 1024 - 32 * 1024 # 1MiB - 32KiB -LEGO_VID = 0x0694 -SPIKE_PRIME_PID = 0x0008 -SPIKE_ESSENTIAL_PID = 0x000C -MINDSTORMS_INVENTOR_PID = 0x0011 + ALL_PIDS = { - MINDSTORMS_INVENTOR_PID: HubKind.TECHNIC_LARGE, - SPIKE_ESSENTIAL_PID: HubKind.TECHNIC_SMALL, - SPIKE_PRIME_PID: HubKind.TECHNIC_LARGE, + MINDSTORMS_INVENTOR_DFU_USB_PID: HubKind.TECHNIC_LARGE, + SPIKE_ESSENTIAL_DFU_USB_PID: HubKind.TECHNIC_SMALL, + SPIKE_PRIME_DFU_USB_PID: HubKind.TECHNIC_LARGE, } -ALL_DEVICES = [f"{LEGO_VID:04x}:{pid:04x}" for pid in ALL_PIDS.keys()] +ALL_DEVICES = [f"{LEGO_USB_VID:04x}:{pid:04x}" for pid in ALL_PIDS.keys()] def _get_dfu_util() -> ContextManager[os.PathLike]: @@ -165,7 +168,7 @@ def flash_dfu(firmware_bin: bytes, metadata: dict) -> None: try: # Determine correct product ID - devices = dfu_upload.get_dfu_devices(idVendor=LEGO_VID) + devices = dfu_upload.get_dfu_devices(idVendor=LEGO_USB_VID) if not devices: print( "No DFU devices found.", @@ -184,11 +187,11 @@ def flash_dfu(firmware_bin: bytes, metadata: dict) -> None: exit(1) # Create dfu file - device = "0x{0:04x}:0x{1:04x}".format(LEGO_VID, product_id) + device = "0x{0:04x}:0x{1:04x}".format(LEGO_USB_VID, product_id) dfu_create.build(outfile, [[target]], device) # Init dfu tool - dfu_upload.__VID = LEGO_VID + dfu_upload.__VID = LEGO_USB_VID dfu_upload.__PID = product_id dfu_upload.init() elements = dfu_upload.read_dfu_file(outfile) diff --git a/pybricksdev/usb/__init__.py b/pybricksdev/usb/__init__.py new file mode 100644 index 0000000..ccce97e --- /dev/null +++ b/pybricksdev/usb/__init__.py @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: MIT +# Copyright (c) 2025 The Pybricks Authors + +# Official LEGO USB identifiers +LEGO_USB_VID = 0x0694 +EV3_USB_PID = 0x0005 +EV3_BOOTLOADER_USB_PID = 0x0006 +SPIKE_PRIME_DFU_USB_PID = 0x0008 +SPIKE_ESSENTIAL_DFU_USB_PID = 0x000C +MINDSTORMS_INVENTOR_DFU_USB_PID = 0x0011 diff --git a/pyproject.toml b/pyproject.toml index 0044db6..3b14641 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -78,6 +78,7 @@ target-version = ['py38'] [tool.isort] profile = "black" src_paths = ["demo", "pybricksdev", "tests"] +known_third_party = ["usb"] [tool.pytest.ini_options] asyncio_mode = "strict"