Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ include = ["typemap", "typemap.*", "typemap_extensions"]
test = [
"pytest>=7.0",
"ruff",
"mypy @ git+https://github.com/msullivan/mypy-typemap@f127ae7a0b79b0d6b3fee9c82e75e62a12ac39e3",
"mypy @ git+https://github.com/msullivan/mypy-typemap@711205f297cfe94c998a39b6b252add796378cb1",
]

[tool.uv]
Expand Down
2 changes: 1 addition & 1 deletion tests/test_dataclass_like.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def _check_hero_init() -> None:
p.name,
p.type,
# All arguments are keyword-only
Literal["keyword"],
Literal[typing.ParamKind.KEYWORD_ONLY],
# GetDefault is Never when there's no default, so use it
# directly as D.
GetDefault[p.init],
Expand Down
8 changes: 6 additions & 2 deletions tests/test_eval_call_with_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
Iter,
Members,
Param,
ParamKind,
Params,
)

Expand All @@ -30,7 +31,10 @@ def test_eval_call_with_types_callable_02():

def test_eval_call_with_types_callable_03():
res = eval_call_with_types(
Callable[Params[Param[Literal["x"], int, Literal["keyword"]]], int],
Callable[
Params[Param[Literal["x"], int, Literal[ParamKind.KEYWORD_ONLY]]],
int,
],
x=int,
)
assert res is int
Expand Down Expand Up @@ -75,7 +79,7 @@ class C: ...
Callable[
Params[
Param[Literal["self"], Self],
Param[Literal["x"], int, Literal["keyword"]],
Param[Literal["x"], int, Literal[ParamKind.KEYWORD_ONLY]],
],
int,
],
Expand Down
3 changes: 2 additions & 1 deletion tests/test_fastapilike_1.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
Member,
Members,
Param,
ParamKind,
Params,
)

Expand Down Expand Up @@ -57,7 +58,7 @@ class _Default:
Param[
p.name,
DropAnnotations[p.type],
Literal["keyword"],
Literal[ParamKind.KEYWORD_ONLY],
DropAnnotations[p.type]
if IsAssignable[
Literal[PropQuals.HAS_DEFAULT],
Expand Down
2 changes: 1 addition & 1 deletion tests/test_fastapilike_2.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ class Field[T: FieldArgs](typing.InitField[T]):
p.name,
p.type,
# All arguments are keyword-only
Literal["keyword"],
Literal[typing.ParamKind.KEYWORD_ONLY],
# GetDefault is Never when there's no default, so use it
# directly as D.
GetDefault[p.init],
Expand Down
10 changes: 5 additions & 5 deletions tests/test_type_dir.py
Original file line number Diff line number Diff line change
Expand Up @@ -385,9 +385,9 @@ def test_type_members_func_1():
str(typ)
== "\
typing.Callable[\
typemap.typing.Params[typemap.typing.Param[typing.Literal['self'], tests.test_type_dir.Base[int], typing.Literal['positional_or_keyword'], typing.Never], \
typemap.typing.Param[typing.Literal['a'], int | None, typing.Literal['positional_or_keyword'], typing.Never], \
typemap.typing.Param[typing.Literal['b'], int, typing.Literal['keyword'], typing.Literal[0]]], \
typemap.typing.Params[typemap.typing.Param[typing.Literal['self'], tests.test_type_dir.Base[int], typing.Literal[<ParamKind.POSITIONAL_OR_KEYWORD: 1>], typing.Never], \
typemap.typing.Param[typing.Literal['a'], int | None, typing.Literal[<ParamKind.POSITIONAL_OR_KEYWORD: 1>], typing.Never], \
typemap.typing.Param[typing.Literal['b'], int, typing.Literal[<ParamKind.KEYWORD_ONLY: 3>], typing.Literal[0]]], \
dict[str, int]]"
)

Expand All @@ -405,7 +405,7 @@ def test_type_members_func_2():
assert (
str(typ)
== "\
classmethod[tests.test_type_dir.Base[int], typemap.typing.Params[typemap.typing.Param[typing.Literal['a'], int | None, typing.Literal['positional_or_keyword'], typing.Never], typemap.typing.Param[typing.Literal['b'], ~K, typing.Literal['positional_or_keyword'], typing.Never]], dict[str, int]]"
classmethod[tests.test_type_dir.Base[int], typemap.typing.Params[typemap.typing.Param[typing.Literal['a'], int | None, typing.Literal[<ParamKind.POSITIONAL_OR_KEYWORD: 1>], typing.Never], typemap.typing.Param[typing.Literal['b'], ~K, typing.Literal[<ParamKind.POSITIONAL_OR_KEYWORD: 1>], typing.Never]], dict[str, int]]"
)


Expand All @@ -424,7 +424,7 @@ def test_type_members_func_3():
)
assert (
str(evaled)
== "staticmethod[typemap.typing.Params[typemap.typing.Param[typing.Literal['a'], int | typing.Literal['gotcha!'] | Z | None, typing.Literal['positional_or_keyword'], typing.Never], typemap.typing.Param[typing.Literal['b'], ~K, typing.Literal['positional_or_keyword'], typing.Never]], dict[str, int | Z]]"
== "staticmethod[typemap.typing.Params[typemap.typing.Param[typing.Literal['a'], int | typing.Literal['gotcha!'] | Z | None, typing.Literal[<ParamKind.POSITIONAL_OR_KEYWORD: 1>], typing.Never], typemap.typing.Param[typing.Literal['b'], ~K, typing.Literal[<ParamKind.POSITIONAL_OR_KEYWORD: 1>], typing.Never]], dict[str, int | Z]]"
)


Expand Down
109 changes: 64 additions & 45 deletions tests/test_type_eval.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
NewProtocol,
Overloaded,
Param,
ParamKind,
Params,
Slice,
SpecialFormEllipsis,
Expand Down Expand Up @@ -155,13 +156,18 @@ def test_eval_types_4():
d = eval_typing(
Callable[
[
Param[Literal["a"], int, Literal["positional"]],
Param[Literal["a"], int, Literal[ParamKind.POSITIONAL_ONLY]],
Param[Literal["b"], int],
Param[Literal["c"], int, Literal["positional_or_keyword"], int],
Param[None, int, Literal["*"]],
Param[Literal["d"], int, Literal["keyword"]],
Param[Literal["e"], int, Literal["keyword"], int],
Param[None, int, Literal["**"]],
Param[
Literal["c"],
int,
Literal[ParamKind.POSITIONAL_OR_KEYWORD],
int,
],
Param[None, int, Literal[ParamKind.VAR_POSITIONAL]],
Param[Literal["d"], int, Literal[ParamKind.KEYWORD_ONLY]],
Param[Literal["e"], int, Literal[ParamKind.KEYWORD_ONLY], int],
Param[None, int, Literal[ParamKind.VAR_KEYWORD]],
],
int,
]
Expand All @@ -170,13 +176,18 @@ def test_eval_types_4():
d
== Callable[
[
Param[Literal["a"], int, Literal["positional"]],
Param[Literal["a"], int, Literal[ParamKind.POSITIONAL_ONLY]],
Param[Literal["b"], int],
Param[Literal["c"], int, Literal["positional_or_keyword"], int],
Param[None, int, Literal["*"]],
Param[Literal["d"], int, Literal["keyword"]],
Param[Literal["e"], int, Literal["keyword"], int],
Param[None, int, Literal["**"]],
Param[
Literal["c"],
int,
Literal[ParamKind.POSITIONAL_OR_KEYWORD],
int,
],
Param[None, int, Literal[ParamKind.VAR_POSITIONAL]],
Param[Literal["d"], int, Literal[ParamKind.KEYWORD_ONLY]],
Param[Literal["e"], int, Literal[ParamKind.KEYWORD_ONLY], int],
Param[None, int, Literal[ParamKind.VAR_KEYWORD]],
],
int,
]
Expand Down Expand Up @@ -765,8 +776,8 @@ def test_eval_getarg_callable_old():
assert (
args
== Params[
Param[Literal[None], Any, Literal["*"]],
Param[Literal[None], Any, Literal["**"]],
Param[Literal[None], Any, Literal[ParamKind.VAR_POSITIONAL]],
Param[Literal[None], Any, Literal[ParamKind.VAR_KEYWORD]],
]
)

Expand All @@ -775,8 +786,8 @@ def test_eval_getarg_callable_old():
assert (
args
== Params[
Param[Literal[None], Any, Literal["*"]],
Param[Literal[None], Any, Literal["**"]],
Param[Literal[None], Any, Literal[ParamKind.VAR_POSITIONAL]],
Param[Literal[None], Any, Literal[ParamKind.VAR_KEYWORD]],
]
)

Expand Down Expand Up @@ -804,8 +815,8 @@ def test_eval_getarg_callable_01():
assert (
args
== Params[
Param[Literal[None], Any, Literal["*"]],
Param[Literal[None], Any, Literal["**"]],
Param[Literal[None], Any, Literal[ParamKind.VAR_POSITIONAL]],
Param[Literal[None], Any, Literal[ParamKind.VAR_KEYWORD]],
]
)

Expand All @@ -814,8 +825,8 @@ def test_eval_getarg_callable_01():
assert (
args
== Params[
Param[Literal[None], Any, Literal["*"]],
Param[Literal[None], Any, Literal["**"]],
Param[Literal[None], Any, Literal[ParamKind.VAR_POSITIONAL]],
Param[Literal[None], Any, Literal[ParamKind.VAR_KEYWORD]],
]
)

Expand All @@ -839,9 +850,9 @@ def test_eval_getarg_callable_02():
# Params wrapped
f = Callable[
[
Param[Literal[None], T, Literal["positional"]],
Param[Literal[None], T, Literal[ParamKind.POSITIONAL_ONLY]],
Param[Literal["y"], T],
Param[Literal["z"], T, Literal["keyword"]],
Param[Literal["z"], T, Literal[ParamKind.KEYWORD_ONLY]],
],
T,
]
Expand Down Expand Up @@ -885,10 +896,10 @@ def f(self, x: int, /, y: int, *, z: int) -> int: ...
assert (
t
== Params[
Param[Literal["self"], C, Literal["positional"]],
Param[Literal["x"], int, Literal["positional"]],
Param[Literal["self"], C, Literal[ParamKind.POSITIONAL_ONLY]],
Param[Literal["x"], int, Literal[ParamKind.POSITIONAL_ONLY]],
Param[Literal["y"], int],
Param[Literal["z"], int, Literal["keyword"]],
Param[Literal["z"], int, Literal[ParamKind.KEYWORD_ONLY]],
]
)
t = eval_typing(GetArg[f, Callable, Literal[1]])
Expand All @@ -899,10 +910,10 @@ def f(self, x: int, /, y: int, *, z: int) -> int: ...
assert (
t
== Params[
Param[Literal["self"], Self, Literal["positional"]],
Param[Literal["x"], int, Literal["positional"]],
Param[Literal["self"], Self, Literal[ParamKind.POSITIONAL_ONLY]],
Param[Literal["x"], int, Literal[ParamKind.POSITIONAL_ONLY]],
Param[Literal["y"], int],
Param[Literal["z"], int, Literal["keyword"]],
Param[Literal["z"], int, Literal[ParamKind.KEYWORD_ONLY]],
]
)
t = eval_typing(GetArg[f, Callable, Literal[1]])
Expand All @@ -922,9 +933,9 @@ def f(cls, x: int, /, y: int, *, z: int) -> int: ...
assert (
t
== Params[
Param[Literal["x"], int, Literal["positional"]],
Param[Literal["x"], int, Literal[ParamKind.POSITIONAL_ONLY]],
Param[Literal["y"], int],
Param[Literal["z"], int, Literal["keyword"]],
Param[Literal["z"], int, Literal[ParamKind.KEYWORD_ONLY]],
]
)
t = eval_typing(GetArg[f, classmethod, Literal[2]])
Expand All @@ -936,9 +947,9 @@ def f(cls, x: int, /, y: int, *, z: int) -> int: ...
assert (
t
== Params[
Param[Literal["x"], int, Literal["positional"]],
Param[Literal["x"], int, Literal[ParamKind.POSITIONAL_ONLY]],
Param[Literal["y"], int],
Param[Literal["z"], int, Literal["keyword"]],
Param[Literal["z"], int, Literal[ParamKind.KEYWORD_ONLY]],
]
)
t = eval_typing(GetArg[f, classmethod, Literal[2]])
Expand All @@ -956,9 +967,9 @@ def f(x: int, /, y: int, *, z: int) -> int: ...
assert (
t
== Params[
Param[Literal["x"], int, Literal["positional"]],
Param[Literal["x"], int, Literal[ParamKind.POSITIONAL_ONLY]],
Param[Literal["y"], int],
Param[Literal["z"], int, Literal["keyword"]],
Param[Literal["z"], int, Literal[ParamKind.KEYWORD_ONLY]],
]
)
t = eval_typing(GetArg[f, staticmethod, Literal[1]])
Expand All @@ -969,9 +980,9 @@ def f(x: int, /, y: int, *, z: int) -> int: ...
assert (
t
== Params[
Param[Literal["x"], int, Literal["positional"]],
Param[Literal["x"], int, Literal[ParamKind.POSITIONAL_ONLY]],
Param[Literal["y"], int],
Param[Literal["z"], int, Literal["keyword"]],
Param[Literal["z"], int, Literal[ParamKind.KEYWORD_ONLY]],
]
)
t = eval_typing(GetArg[f, staticmethod, Literal[1]])
Expand Down Expand Up @@ -1827,11 +1838,13 @@ def test_callable_to_signature_01():
Params[
Param[None, int],
Param[Literal["b"], int],
Param[Literal["c"], int, Literal["positional_or_keyword"], int],
Param[None, int, Literal["*"]],
Param[Literal["d"], int, Literal["keyword"]],
Param[Literal["e"], int, Literal["keyword"], int],
Param[None, int, Literal["**"]],
Param[
Literal["c"], int, Literal[ParamKind.POSITIONAL_OR_KEYWORD], int
],
Param[None, int, Literal[ParamKind.VAR_POSITIONAL]],
Param[Literal["d"], int, Literal[ParamKind.KEYWORD_ONLY]],
Param[Literal["e"], int, Literal[ParamKind.KEYWORD_ONLY], int],
Param[None, int, Literal[ParamKind.VAR_KEYWORD]],
],
int,
]
Expand All @@ -1850,10 +1863,16 @@ def test_callable_to_signature_01():
def test_callable_to_signature_multi_kind_error():
from typemap.type_eval._eval_operators import _callable_type_to_signature

# Param can carry at most one kind; combining "positional" with
# "keyword" is nonsense and should be rejected.
# Param can carry at most one kind; combining POSITIONAL_ONLY with
# KEYWORD_ONLY is nonsense and should be rejected.
callable_type = Callable[
Params[Param[Literal["x"], int, Literal["positional", "keyword"]]],
Params[
Param[
Literal["x"],
int,
Literal[ParamKind.POSITIONAL_ONLY, ParamKind.KEYWORD_ONLY],
]
],
int,
]
with pytest.raises(TypeError, match="at most one"):
Expand All @@ -1864,7 +1883,7 @@ def test_callable_to_signature_never_kind_error():
from typemap.type_eval._eval_operators import _callable_type_to_signature

# Never is not a valid kind; the explicit "normal" kind is
# Literal["positional_or_keyword"].
# Literal[ParamKind.POSITIONAL_OR_KEYWORD] (the default).
callable_type = Callable[
Params[Param[Literal["x"], int, Never]],
int,
Expand Down
Loading
Loading