diff --git a/homeassistant/components/crownstone/helpers.py b/homeassistant/components/crownstone/helpers.py index 0dc86ea5f36..4da8bc8dbe7 100644 --- a/homeassistant/components/crownstone/helpers.py +++ b/homeassistant/components/crownstone/helpers.py @@ -2,6 +2,7 @@ from __future__ import annotations +from collections.abc import Sequence import os from serial.tools.list_ports_common import ListPortInfo @@ -12,7 +13,7 @@ from .const import DONT_USE_USB, MANUAL_PATH, REFRESH_LIST def list_ports_as_str( - serial_ports: list[ListPortInfo], no_usb_option: bool = True + serial_ports: Sequence[ListPortInfo], no_usb_option: bool = True ) -> list[str]: """Represent currently available serial ports as string. diff --git a/homeassistant/components/usb/__init__.py b/homeassistant/components/usb/__init__.py index 2da72d16ac6..4517501bf43 100644 --- a/homeassistant/components/usb/__init__.py +++ b/homeassistant/components/usb/__init__.py @@ -2,13 +2,13 @@ from __future__ import annotations -from collections.abc import Coroutine +from collections.abc import Coroutine, Sequence import dataclasses import fnmatch import logging import os import sys -from typing import TYPE_CHECKING, Any +from typing import TYPE_CHECKING, Any, overload from serial.tools.list_ports import comports from serial.tools.list_ports_common import ListPortInfo @@ -116,6 +116,7 @@ class UsbServiceInfo(BaseServiceInfo): description: str | None +@overload def human_readable_device_name( device: str, serial_number: str | None, @@ -123,11 +124,32 @@ def human_readable_device_name( description: str | None, vid: str | None, pid: str | None, +) -> str: ... + + +@overload +def human_readable_device_name( + device: str, + serial_number: str | None, + manufacturer: str | None, + description: str | None, + vid: int | None, + pid: int | None, +) -> str: ... + + +def human_readable_device_name( + device: str, + serial_number: str | None, + manufacturer: str | None, + description: str | None, + vid: str | int | None, + pid: str | int | None, ) -> str: """Return a human readable name from USBDevice attributes.""" device_details = f"{device}, s/n: {serial_number or 'n/a'}" manufacturer_details = f" - {manufacturer}" if manufacturer else "" - vendor_details = f" - {vid}:{pid}" if vid else "" + vendor_details = f" - {vid}:{pid}" if vid is not None else "" full_details = f"{device_details}{manufacturer_details}{vendor_details}" if not description: @@ -360,7 +382,7 @@ class USBDiscovery: service_info, ) - async def _async_process_ports(self, ports: list[ListPortInfo]) -> None: + async def _async_process_ports(self, ports: Sequence[ListPortInfo]) -> None: """Process each discovered port.""" usb_devices = [ usb_device_from_port(port) diff --git a/homeassistant/components/zha/config_flow.py b/homeassistant/components/zha/config_flow.py index 9c515c315b7..5cb67489423 100644 --- a/homeassistant/components/zha/config_flow.py +++ b/homeassistant/components/zha/config_flow.py @@ -102,7 +102,8 @@ def _format_backup_choice( async def list_serial_ports(hass: HomeAssistant) -> list[ListPortInfo]: """List all serial ports, including the Yellow radio and the multi-PAN addon.""" - ports = await hass.async_add_executor_job(serial.tools.list_ports.comports) + ports: list[ListPortInfo] = [] + ports.extend(await hass.async_add_executor_job(serial.tools.list_ports.comports)) # Add useful info to the Yellow's serial port selection screen try: diff --git a/requirements_test.txt b/requirements_test.txt index 51788eda2a0..ce9743d758e 100644 --- a/requirements_test.txt +++ b/requirements_test.txt @@ -45,6 +45,7 @@ types-paho-mqtt==1.6.0.20240321 types-pillow==10.2.0.20240822 types-protobuf==5.29.1.20241207 types-psutil==6.1.0.20241221 +types-pyserial==3.5.0.20241221 types-python-dateutil==2.9.0.20241206 types-python-slugify==8.0.2.20240310 types-pytz==2024.2.0.20241221