Skip to content

Commit 6728d7c

Browse files
authored
Enable mypy for typemap (#3)
`tests` is still busted (maybe fundamentally until we have typechecking?)
1 parent d191824 commit 6728d7c

6 files changed

Lines changed: 19 additions & 15 deletions

File tree

tests/test_cqa.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ def test_cqa_ruff_check(project_root):
2929

3030
def test_cqa_ruff_format_check(project_root):
3131
"""Test that code is properly formatted according to ruff."""
32-
# Ruff format respects pyproject.toml exclusions (_vendor is excluded)
32+
# Ruff format respects pyproject.toml exclusions
3333
result = subprocess.run(
3434
[sys.executable, "-m", "ruff", "format", "--check", "."],
3535
capture_output=True,
@@ -43,12 +43,11 @@ def test_cqa_ruff_format_check(project_root):
4343
)
4444

4545

46-
@pytest.mark.skip(reason="Mypy is not working yet")
4746
def test_cqa_mypy(project_root):
4847
"""Test that code passes mypy type checking."""
4948
# Mypy uses configuration from pyproject.toml
50-
# Run on the whole project (pi package and tests), excluding _vendor
51-
for subdir in ["pi", "tests/fixtures"]:
49+
# Run on typemap -- tests not ready yet
50+
for subdir in ["typemap"]:
5251
result = subprocess.run(
5352
[
5453
sys.executable,

typemap/__init__.py

Whitespace-only changes.

typemap/type_eval/_apply_generic.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ def _box(cls: type[Any], args: dict[str, Any]) -> Boxed:
7777

7878
return Boxed(cls, boxed_bases, args)
7979

80-
if isinstance(cls, (typing._GenericAlias, types.GenericAlias)):
80+
if isinstance(cls, (typing._GenericAlias, types.GenericAlias)): # type: ignore[attr-defined]
8181
# XXX this feels out of place, `box()` needs to only accept types.
8282
args = dict(
8383
zip(cls.__origin__.__parameters__, cls.__args__, strict=True)
@@ -184,7 +184,7 @@ def apply(cls: type[Any]) -> dict[str, Any]:
184184
annos.update(af)
185185

186186
for name, stuff in boxed.cls.__dict__.items():
187-
if name in typing.EXCLUDED_ATTRIBUTES:
187+
if name in typing.EXCLUDED_ATTRIBUTES: # type: ignore[attr-defined]
188188
continue
189189

190190
stuff = inspect.unwrap(stuff)

typemap/type_eval/_eval_call.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@ def eval_call(func: types.FunctionType, /, *args: Any, **kwargs: Any) -> Any:
1616

1717

1818
def _eval_call(func: types.FunctionType, /, *args: Any, **kwargs: Any) -> Any:
19-
vars = {}
19+
vars: dict[str, Any] = {}
2020

2121
params = func.__type_params__
2222
for p in params:
23-
if p.__bound__ is next.CallSpec:
23+
if hasattr(p, "__bound__") and p.__bound__ is next.CallSpec:
2424
vars[p.__name__] = next._CallSpecWrapper(args, kwargs, func)
2525
else:
2626
vars[p.__name__] = p
@@ -29,6 +29,8 @@ def _eval_call(func: types.FunctionType, /, *args: Any, **kwargs: Any) -> Any:
2929
af = func.__annotate__
3030
except AttributeError:
3131
raise ValueError("func has no __annotate__ attribute")
32+
if not af:
33+
raise ValueError("func has no __annotate__ attribute")
3234

3335
af_args = tuple(
3436
types.CellType(vars[name]) for name in af.__code__.co_freevars

typemap/type_eval/_eval_typing.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ def _eval_type_type(obj: type, ctx: EvalContext):
9999
if isinstance(obj, type) and issubclass(obj, typing.Generic):
100100
ret = type(
101101
obj.__name__,
102-
(typing.Protocol,),
102+
(typing.cast(type, typing.Protocol),),
103103
{
104104
"__module__": obj.__module__,
105105
"__name__": obj.__name__,
@@ -129,6 +129,7 @@ def _eval_type_var(obj: typing.TypeVar, ctx: EvalContext):
129129

130130
@_eval_types_impl.register
131131
def _eval_type_alias(obj: typing.TypeAliasType, ctx: EvalContext):
132+
assert obj.__module__ # FIXME: or can this really happen?
132133
func = obj.evaluate_value
133134
mod = sys.modules[obj.__module__]
134135
ff = types.FunctionType(func.__code__, mod.__dict__, None, None, ())
@@ -142,7 +143,7 @@ def _eval_generic(obj: types.GenericAlias, ctx: EvalContext):
142143
# This is a GenericAlias over a Python class, e.g. `dict[str, int]`
143144
# Let's reconstruct it by evaluating all arguments
144145
new_args = tuple(_eval_types(arg, ctx) for arg in obj.__args__)
145-
return obj.__origin__[new_args]
146+
return obj.__origin__[new_args] # type: ignore[index]
146147

147148
func = obj.evaluate_value
148149

@@ -169,5 +170,6 @@ def _eval_generic(obj: types.GenericAlias, ctx: EvalContext):
169170

170171
@_eval_types_impl.register
171172
def _eval_union(obj: typing.Union, ctx: EvalContext): # type: ignore
172-
new_args = tuple(_eval_types(arg, ctx) for arg in obj.__args__)
173+
args: typing.Sequence[typing.Any] = obj.__args__
174+
new_args = tuple(_eval_types(arg, ctx) for arg in args)
173175
return typing.Union[new_args]

typemap/typing.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ class CallSpec:
1616
class _CallSpecWrapper:
1717
_args: tuple[typing.Any]
1818
_kwargs: dict[str, typing.Any]
19-
_func: types.FunctionType | types.MethodType
19+
# TODO: Support MethodType!
20+
_func: types.FunctionType # | types.MethodType
2021

2122
@property
2223
def args(self) -> None:
@@ -32,7 +33,7 @@ class _CallKwarg:
3233
name: str
3334

3435

35-
@typing._SpecialForm
36+
@typing._SpecialForm # type: ignore[call-arg]
3637
def CallSpecKwargs(self, spec: _CallSpecWrapper) -> list[_CallKwarg]:
3738
ff = types.FunctionType(
3839
spec._func.__code__,
@@ -85,7 +86,7 @@ class DirProperties(metaclass=DirPropertiesMeta):
8586

8687
class NewProtocolMeta(type):
8788
def __getitem__(cls, val: list[Property]):
88-
dct = {}
89+
dct: dict[str, object] = {}
8990
dct["__annotations__"] = {prop.name: prop.type for prop in val}
9091

9192
module_name = __name__
@@ -99,7 +100,7 @@ def __getitem__(cls, val: list[Property]):
99100

100101
dct["__module__"] = module_name
101102

102-
mcls = type(typing.Protocol)
103+
mcls: type = type(typing.cast(type, typing.Protocol))
103104
cls = mcls(name, (typing.Protocol,), dct)
104105
return cls
105106

0 commit comments

Comments
 (0)