Skip to content

Commit bb33f7c

Browse files
fix(modules): use parse from packaging module (#14732)
1 parent 45b6fa9 commit bb33f7c

File tree

2 files changed

+32
-6
lines changed

2 files changed

+32
-6
lines changed

api/src/opentrons/hardware_control/modules/mod_abc.py

+13-6
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@
22
import asyncio
33
import logging
44
import re
5-
from pkg_resources import parse_version
6-
from typing import ClassVar, Mapping, Optional, cast, TypeVar
7-
5+
from typing import ClassVar, Mapping, Optional, TypeVar
6+
from packaging.version import InvalidVersion, parse, Version
87
from opentrons.config import IS_ROBOT, ROBOT_FIRMWARE_DIR
98
from opentrons.drivers.rpi_drivers.types import USBPort
109

@@ -16,6 +15,14 @@
1615
TaskPayload = TypeVar("TaskPayload")
1716

1817

18+
def parse_fw_version(version: str) -> Version:
19+
try:
20+
device_version = parse(version)
21+
except InvalidVersion:
22+
device_version = parse("v0.0.0")
23+
return device_version
24+
25+
1926
class AbstractModule(abc.ABC):
2027
"""Defines the common methods of a module."""
2128

@@ -88,9 +95,9 @@ def get_bundled_fw(self) -> Optional[BundledFirmware]:
8895
def has_available_update(self) -> bool:
8996
"""Return whether a newer firmware file is available"""
9097
if self.device_info and self._bundled_fw:
91-
device_version = parse_version(self.device_info["version"])
92-
available_version = parse_version(self._bundled_fw.version)
93-
return cast(bool, available_version > device_version)
98+
device_version = parse_fw_version(self.device_info["version"])
99+
available_version = parse_fw_version(self._bundled_fw.version)
100+
return available_version > device_version
94101
return False
95102

96103
async def wait_for_is_running(self) -> None:

api/tests/opentrons/hardware_control/test_modules.py

+19
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
from pathlib import Path
55
from unittest import mock
6+
from packaging.version import Version
67

78
from opentrons.hardware_control import ExecutionManager
89
from opentrons.hardware_control.modules import ModuleAtPort
@@ -22,6 +23,7 @@
2223
HeaterShaker,
2324
AbstractModule,
2425
)
26+
from opentrons.hardware_control.modules.mod_abc import parse_fw_version
2527
from opentrons.drivers.rpi_drivers.types import USBPort
2628

2729

@@ -422,3 +424,20 @@ def test_magnetic_module_revision_parsing(revision, model):
422424
)
423425
def test_temperature_module_revision_parsing(revision, model):
424426
assert TempDeck._model_from_revision(revision) == model
427+
428+
429+
@pytest.mark.parametrize(
430+
argnames=["device_version", "expected_result"],
431+
argvalues=[
432+
["v1.0.4", Version("v1.0.4")],
433+
["v0.5.6", Version("v0.5.6")],
434+
["v1.0.4-dhfs", Version("v0.0.0")],
435+
["v3.0.dshjfd", Version("v0.0.0")],
436+
],
437+
)
438+
async def test_catch_invalid_fw_version(
439+
device_version: str,
440+
expected_result: bool,
441+
) -> None:
442+
"""Assert that invalid firmware versions prompt a valid Version object of v0.0.0."""
443+
assert parse_fw_version(device_version) == expected_result

0 commit comments

Comments
 (0)