Skip to content

Commit 39a705f

Browse files
JacobCoffeeclaude
andcommitted
fix: add type annotations for dynamically imported test modules
Add explicit type annotations to help ty type checker understand dynamically imported modules (dto and serialization). Use cast() for decoded JSON/msgpack objects to satisfy type checker. Resolves 9 ty type checking errors: - unresolved-attribute for dto.config - unresolved-attribute for serialization module attributes - non-subscriptable for decoded JSON/msgpack results 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent bd0163a commit 39a705f

File tree

3 files changed

+31
-21
lines changed

3 files changed

+31
-21
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"tailwindcss": "^3.3.3"
99
},
1010
"devDependencies": {
11+
"@biomejs/biome": "2.3.7",
1112
"daisyui": "^3.5.0"
1213
}
1314
}

tests/unit/api/test_dto.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,21 @@
55
import importlib.util
66
import sys
77
from pathlib import Path
8+
from typing import TYPE_CHECKING
89

910
from litestar.dto import DTOConfig
1011

12+
if TYPE_CHECKING:
13+
from collections.abc import Callable
14+
1115
# Import the dto module directly without triggering __init__.py
1216
dto_path = Path(__file__).parent.parent.parent.parent / "services" / "api" / "src" / "byte_api" / "lib" / "dto.py"
1317
spec = importlib.util.spec_from_file_location("dto", dto_path)
1418
dto = importlib.util.module_from_spec(spec) # type: ignore[arg-type]
1519
sys.modules["dto"] = dto
1620
spec.loader.exec_module(dto) # type: ignore[union-attr]
1721

18-
config = dto.config
22+
config: Callable[..., DTOConfig] = dto.config # type: ignore[attr-defined]
1923

2024
__all__ = [
2125
"TestDTOConfig",

tests/unit/api/test_serialization.py

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,16 @@
77
import sys
88
from json import dumps as json_dumps
99
from pathlib import Path
10+
from typing import TYPE_CHECKING, Any, cast
1011
from uuid import uuid4
1112

1213
import pytest
1314
from pydantic import BaseModel
1415

16+
if TYPE_CHECKING:
17+
from collections.abc import Callable
18+
from json import JSONEncoder
19+
1520
# Import the serialization module directly without triggering __init__.py
1621
serialization_path = (
1722
Path(__file__).parent.parent.parent.parent / "services" / "api" / "src" / "byte_api" / "lib" / "serialization.py"
@@ -21,14 +26,14 @@
2126
sys.modules["serialization"] = serialization
2227
spec.loader.exec_module(serialization) # type: ignore[union-attr]
2328

24-
UUIDEncoder = serialization.UUIDEncoder
25-
convert_camel_to_snake_case = serialization.convert_camel_to_snake_case
26-
convert_datetime_to_gmt = serialization.convert_datetime_to_gmt
27-
convert_string_to_camel_case = serialization.convert_string_to_camel_case
28-
from_json = serialization.from_json
29-
from_msgpack = serialization.from_msgpack
30-
to_json = serialization.to_json
31-
to_msgpack = serialization.to_msgpack
29+
UUIDEncoder: type[JSONEncoder] = serialization.UUIDEncoder # type: ignore[attr-defined]
30+
convert_camel_to_snake_case: Callable[[str], str] = serialization.convert_camel_to_snake_case # type: ignore[attr-defined]
31+
convert_datetime_to_gmt: Callable[[datetime.datetime], str] = serialization.convert_datetime_to_gmt # type: ignore[attr-defined]
32+
convert_string_to_camel_case: Callable[[str], str] = serialization.convert_string_to_camel_case # type: ignore[attr-defined]
33+
from_json: Callable[..., object] = serialization.from_json # type: ignore[attr-defined]
34+
from_msgpack: Callable[..., object] = serialization.from_msgpack # type: ignore[attr-defined]
35+
to_json: Callable[..., str] = serialization.to_json # type: ignore[attr-defined]
36+
to_msgpack: Callable[..., bytes] = serialization.to_msgpack # type: ignore[attr-defined]
3237

3338
__all__ = [
3439
"TestCaseConversion",
@@ -82,7 +87,7 @@ def test_roundtrip_json(self) -> None:
8287
"""Test JSON encode/decode roundtrip."""
8388
original = {"test": "data", "nested": {"value": 123}}
8489
encoded = to_json(original)
85-
decoded = from_json(encoded)
90+
decoded = cast(dict[str, Any], from_json(encoded))
8691

8792
assert decoded == original
8893

@@ -127,7 +132,7 @@ def test_to_json_with_deeply_nested_structures(self) -> None:
127132
result = to_json(nested)
128133

129134
assert isinstance(result, bytes)
130-
decoded = from_json(result)
135+
decoded = cast(dict[str, Any], from_json(result))
131136
assert decoded["a"]["b"]["c"]["d"]["e"] == "deep"
132137

133138
def test_to_json_with_mixed_nested_types(self) -> None:
@@ -140,15 +145,15 @@ def test_to_json_with_mixed_nested_types(self) -> None:
140145
result = to_json(data)
141146

142147
assert isinstance(result, bytes)
143-
decoded = from_json(result)
148+
decoded = cast(dict[str, Any], from_json(result))
144149
assert decoded == data
145150

146151
def test_to_json_with_empty_structures(self) -> None:
147152
"""Test encoding empty dicts and lists."""
148153
data = {"empty_dict": {}, "empty_list": [], "nested_empty": {"a": []}}
149154
result = to_json(data)
150155

151-
decoded = from_json(result)
156+
decoded = cast(dict[str, Any], from_json(result))
152157
assert decoded == data
153158

154159
def test_to_json_with_special_characters(self) -> None:
@@ -161,15 +166,15 @@ def test_to_json_with_special_characters(self) -> None:
161166
}
162167
result = to_json(data)
163168

164-
decoded = from_json(result)
169+
decoded = cast(dict[str, Any], from_json(result))
165170
assert decoded == data
166171

167172
def test_to_json_with_boolean_and_null(self) -> None:
168173
"""Test encoding boolean and null values."""
169174
data = {"true_val": True, "false_val": False, "null_val": None}
170175
result = to_json(data)
171176

172-
decoded = from_json(result)
177+
decoded = cast(dict[str, Any], from_json(result))
173178
assert decoded == data
174179

175180
def test_to_json_with_large_numbers(self) -> None:
@@ -181,7 +186,7 @@ def test_to_json_with_large_numbers(self) -> None:
181186
}
182187
result = to_json(data)
183188

184-
decoded = from_json(result)
189+
decoded = cast(dict[str, Any], from_json(result))
185190
assert decoded == data
186191

187192

@@ -207,7 +212,7 @@ def test_roundtrip_msgpack(self) -> None:
207212
"""Test MessagePack encode/decode roundtrip."""
208213
original = {"test": "data", "nested": {"value": 123}, "array": [1, 2, 3]}
209214
encoded = to_msgpack(original)
210-
decoded = from_msgpack(encoded)
215+
decoded = cast(dict[str, Any], from_msgpack(encoded))
211216

212217
assert decoded == original
213218

@@ -229,31 +234,31 @@ def test_to_msgpack_with_binary_data(self) -> None:
229234
result = to_msgpack(data)
230235

231236
assert isinstance(result, bytes)
232-
decoded = from_msgpack(result)
237+
decoded = cast(dict[str, Any], from_msgpack(result))
233238
assert decoded == data
234239

235240
def test_to_msgpack_with_deeply_nested_structures(self) -> None:
236241
"""Test MessagePack with deeply nested structures."""
237242
nested = {"a": {"b": {"c": {"d": [1, 2, 3]}}}}
238243
result = to_msgpack(nested)
239244

240-
decoded = from_msgpack(result)
245+
decoded = cast(dict[str, Any], from_msgpack(result))
241246
assert decoded == nested
242247

243248
def test_to_msgpack_with_empty_structures(self) -> None:
244249
"""Test MessagePack with empty dicts and lists."""
245250
data = {"empty": {}, "list": [], "nested": {"a": []}}
246251
result = to_msgpack(data)
247252

248-
decoded = from_msgpack(result)
253+
decoded = cast(dict[str, Any], from_msgpack(result))
249254
assert decoded == data
250255

251256
def test_to_msgpack_with_special_characters(self) -> None:
252257
"""Test MessagePack with unicode and special characters."""
253258
data = {"unicode": "Hello 世界 🌍", "special": "line1\nline2\ttab"}
254259
result = to_msgpack(data)
255260

256-
decoded = from_msgpack(result)
261+
decoded = cast(dict[str, Any], from_msgpack(result))
257262
assert decoded == data
258263

259264
def test_msgpack_handles_encoding_error(self) -> None:

0 commit comments

Comments
 (0)