From ceea505db1fdbb2244c5e52f13dbed6126be7638 Mon Sep 17 00:00:00 2001 From: Cody Edwards Date: Wed, 9 Apr 2025 21:27:07 +0000 Subject: [PATCH] chore: changes for mypy update Signed-off-by: Cody Edwards --- hatch.toml | 2 +- requirements-testing.txt | 2 +- .../adaptor_runtime/_background/model.py | 17 +++++---- .../configuration/_configuration_manager.py | 3 +- .../process/_logging_subprocess.py | 1 + .../unit/background/test_model.py | 36 ++++++++++++++++--- .../test_integration_client_interface.py | 2 ++ 7 files changed, 46 insertions(+), 17 deletions(-) diff --git a/hatch.toml b/hatch.toml index 3d5d8dd3..2fcb32f6 100644 --- a/hatch.toml +++ b/hatch.toml @@ -5,7 +5,7 @@ pre-install-commands = [ [envs.default.scripts] sync = "pip install -r requirements-testing.txt" -test = "pytest --cov-config pyproject.toml {args:test}" +test = "pytest --cov-config pyproject.toml {args:test} -vv" typing = "mypy {args:src test}" style = [ "ruff check {args:.}", diff --git a/requirements-testing.txt b/requirements-testing.txt index 89a448b5..b1fda23e 100644 --- a/requirements-testing.txt +++ b/requirements-testing.txt @@ -6,6 +6,6 @@ pytest-timeout == 2.3.* pytest-xdist == 3.6.* black == 25.* ruff == 0.11.* -mypy == 1.11.* +mypy == 1.15.* psutil == 7.0.* types-PyYAML ~= 6.0 diff --git a/src/openjd/adaptor_runtime/_background/model.py b/src/openjd/adaptor_runtime/_background/model.py index 18b06d35..1f2ca30b 100644 --- a/src/openjd/adaptor_runtime/_background/model.py +++ b/src/openjd/adaptor_runtime/_background/model.py @@ -3,7 +3,8 @@ import dataclasses as dataclasses import json as json from enum import Enum as Enum -from typing import Any, ClassVar, Dict, Generic, Iterable, Type, TypeVar, cast +from enum import EnumMeta +from typing import Any, ClassVar, Dict, Type, TypeVar, cast, Generic from ..adaptors import AdaptorState @@ -100,14 +101,12 @@ def map(self, o: Dict) -> _T: value = o[field.name] if dataclasses.is_dataclass(field.type): - value = DataclassMapper(field.type).map(value) - elif issubclass(field.type, Enum): - [value] = [ - enum - # Need to cast here for mypy - for enum in cast(Iterable[Enum], list(field.type)) - if enum.value == value - ] + # The init function expects a type, so any dataclasses in cls + # will be a type. + value = DataclassMapper(cast(type, field.type)).map(value) + elif isinstance(field.type, EnumMeta): + value = field.type(value) + args[field.name] = value return self._cls(**args) diff --git a/src/openjd/adaptor_runtime/adaptors/configuration/_configuration_manager.py b/src/openjd/adaptor_runtime/adaptors/configuration/_configuration_manager.py index 95b0205a..2eb5e5d8 100644 --- a/src/openjd/adaptor_runtime/adaptors/configuration/_configuration_manager.py +++ b/src/openjd/adaptor_runtime/adaptors/configuration/_configuration_manager.py @@ -23,10 +23,11 @@ _ConfigType = TypeVar("_ConfigType", bound=Configuration) _AdaptorConfigType = TypeVar("_AdaptorConfigType", bound=AdaptorConfiguration) +_AdaptorConfigClassType = Type[_AdaptorConfigType] def create_adaptor_configuration_manager( - config_cls: Type[_AdaptorConfigType], + config_cls: _AdaptorConfigClassType, adaptor_name: str, default_config_path: str, schema_path: str | List[str] | None = None, diff --git a/src/openjd/adaptor_runtime/process/_logging_subprocess.py b/src/openjd/adaptor_runtime/process/_logging_subprocess.py index 8376446c..5cfd2294 100644 --- a/src/openjd/adaptor_runtime/process/_logging_subprocess.py +++ b/src/openjd/adaptor_runtime/process/_logging_subprocess.py @@ -177,6 +177,7 @@ def terminate(self, grace_time_s: float = 60) -> None: self._process.kill() self._process.wait() else: + signal_type: signal.Signals if OSName.is_windows(): # pragma: is-posix # We use `CREATE_NEW_PROCESS_GROUP` to create the process, # so pid here is also the process group id and SIGBREAK can be only sent to the process group. diff --git a/test/openjd/adaptor_runtime/unit/background/test_model.py b/test/openjd/adaptor_runtime/unit/background/test_model.py index 3a74b447..e47fc2b1 100644 --- a/test/openjd/adaptor_runtime/unit/background/test_model.py +++ b/test/openjd/adaptor_runtime/unit/background/test_model.py @@ -2,11 +2,22 @@ import dataclasses +from enum import Enum + import pytest from openjd.adaptor_runtime._background.model import DataclassMapper +class StrEnum(str, Enum): + TEST = "test_str" + TEST_UNI = "test_☃" + + +class NormalEnum(Enum): + ONE = 1 + + # Define two dataclasses to use for tests @dataclasses.dataclass class Inner: @@ -17,6 +28,9 @@ class Inner: class Outer: outer_key: str inner: Inner + test_str: StrEnum + test_str_unicode: StrEnum + normal_enum: NormalEnum class TestDataclassMapper: @@ -26,17 +40,29 @@ class TestDataclassMapper: def test_maps_nested_dataclass(self): # GIVEN - input = {"outer_key": "outer_value", "inner": {"key": "value"}} + input = { + "outer_key": "outer_value", + "inner": { + "key": "value", + }, + "test_str": "test_str", + "test_str_unicode": "test_☃", + "normal_enum": 1, + } mapper = DataclassMapper(Outer) # WHEN result = mapper.map(input) # THEN - assert isinstance(result, Outer) - assert isinstance(result.inner, Inner) - assert result.outer_key == "outer_value" - assert result.inner.key == "value" + expected_dataclass = Outer( + outer_key="outer_value", + inner=Inner(key="value"), + test_str=StrEnum.TEST, + test_str_unicode=StrEnum.TEST_UNI, + normal_enum=NormalEnum.ONE, + ) + assert result == expected_dataclass def test_raises_when_field_is_missing(self): # GIVEN diff --git a/test/openjd/adaptor_runtime_client/integ/test_integration_client_interface.py b/test/openjd/adaptor_runtime_client/integ/test_integration_client_interface.py index 1dd09405..98490a73 100644 --- a/test/openjd/adaptor_runtime_client/integ/test_integration_client_interface.py +++ b/test/openjd/adaptor_runtime_client/integ/test_integration_client_interface.py @@ -35,6 +35,7 @@ def test_graceful_shutdown(self) -> None: # To avoid a race condition, giving some extra time for the logging subprocess to start. _sleep(0.5 if OSName.is_posix() else 4) + signal_type: signal.Signals if OSName.is_windows(): signal_type = signal.CTRL_BREAK_EVENT # type: ignore[attr-defined] else: @@ -77,6 +78,7 @@ def test_client_in_thread_does_not_do_graceful_shutdown(self) -> None: # To avoid a race condition, giving some extra time for the logging subprocess to start. _sleep(0.5 if OSName.is_posix() else 4) + signal_type: signal.Signals if OSName.is_windows(): signal_type = signal.CTRL_BREAK_EVENT # type: ignore[attr-defined] else: