Skip to content

Commit

Permalink
Merge pull request #722 from ImperialCollegeLondon/fix-device-enumera…
Browse files Browse the repository at this point in the history
…tion-macos

Fix sorting of port names without terminating numbers
  • Loading branch information
dc2917 authored Nov 29, 2024
2 parents fabb9ab + 85c8996 commit 097ed4c
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 25 deletions.
21 changes: 14 additions & 7 deletions finesse/hardware/serial_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,20 @@ def _port_info_to_str(vendor_id: int, product_id: int, count: int = 0) -> str:
return out


def _get_port_number(port: str) -> int:
"""Get the port number from the end of a port's name."""
match = re.match("[^0-9]*([0-9]+)$", port)
if not match:
raise ValueError(f"Port {port} does not end with a number")
def _get_port_parts(port: str) -> tuple[str, int]:
"""Split the port name into the string prefix and the number suffix.
return int(match.group(1))
If there is no number at the end of the string, (port, -1) will be returned.
"""
match = re.match("^([^0-9])*([0-9]*)$", port)

# NB: This should never fail as the regex should encompass all strings
assert match, "Invalid port name"

num_str = match.group(2)
num = int(num_str) if num_str else -1

return match.group(1), num


def _get_usb_serial_ports(refresh: bool = False) -> dict[str, str]:
Expand All @@ -55,7 +62,7 @@ def _get_usb_serial_ports(refresh: bool = False) -> dict[str, str]:
# additional number to distinguish them
counter: dict[tuple[int, int], int] = {}
_serial_ports = {}
for port in sorted(comports(), key=lambda port: _get_port_number(port.device)):
for port in sorted(comports(), key=lambda port: _get_port_parts(port.device)):
# Vendor ID is a USB-specific field, so we can use this to check whether the
# device is USB or not
if port.vid is None:
Expand Down
27 changes: 9 additions & 18 deletions tests/hardware/test_serial_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from finesse.hardware.serial_device import (
SerialDevice,
_create_serial,
_get_port_number,
_get_port_parts,
_get_usb_serial_ports,
_port_info_to_str,
)
Expand Down Expand Up @@ -57,23 +57,14 @@ def test_get_usb_serial_ports(
}


@pytest.mark.parametrize(
"port,number",
(
(f"{prefix}{number}", number)
for number in (1, 2, 10)
for prefix in ("COM", "/dev/ttyUSB")
),
)
def test_get_port_number(port: str, number: int) -> None:
"""Test _get_port_number()."""
assert _get_port_number(port) == number


def test_get_port_number_bad() -> None:
"""Test _get_port_number() when a bad value is provided."""
with pytest.raises(ValueError):
_get_port_number("NO_NUMBER")
def test_get_port_parts() -> None:
"""Test _get_port_parts()."""
for prefix in ("COM", "/dev/ttyUSB"):
assert _get_port_parts(f"{prefix}1") < _get_port_parts(f"{prefix}2")
assert _get_port_parts(f"{prefix}1") < _get_port_parts(f"{prefix}10")
assert _get_port_parts("A1") < _get_port_parts("B1")
assert _get_port_parts("A") < _get_port_parts("A0")
assert _get_port_parts("A") < _get_port_parts("B")


@pytest.mark.parametrize("refresh", (False, True))
Expand Down

0 comments on commit 097ed4c

Please sign in to comment.