Skip to content
Draft
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@fbc5d6c16834379307857318e6c32326b5d8a201",
"mypy @ git+https://github.com/msullivan/mypy-typemap@5250279d38109fedafff709488939c38901783bd",
]

[tool.uv]
Expand Down
13 changes: 7 additions & 6 deletions tests/test_astlike_1.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
IsAssignable,
Iter,
IsEquivalent,
Map,
Member,
NewProtocol,
RaiseError,
Expand Down Expand Up @@ -46,7 +47,7 @@


type CombineVarArgs[Ls: tuple[VarArg], Rs: tuple[VarArg]] = tuple[
*[
*Map(
VarArg[
VarArgName[x],
(
Expand All @@ -56,7 +57,7 @@
)
else GetArg[ # Common to both Ls and Rs
tuple[
*[
*Map(
(
VarArgType[x]
if IsAssignable[VarArgType[x], VarArgType[y]]
Expand All @@ -73,22 +74,22 @@
)
for y in Iter[Rs]
if IsEquivalent[VarArgName[x], VarArgName[y]]
]
)
],
tuple,
typing.Literal[0],
]
),
]
for x in Iter[Ls]
],
*[ # Unique to Rs
),
*Map( # Unique to Rs
x
for x in Iter[Rs]
if not any( # Unique to Rs
IsEquivalent[VarArgName[x], VarArgName[y]] for y in Iter[Ls]
)
],
),
]


Expand Down
3 changes: 2 additions & 1 deletion tests/test_call.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
Attrs,
BaseTypedDict,
NewProtocol,
Map,
Member,
Iter,
)
Expand All @@ -17,7 +18,7 @@
def func[*T, K: BaseTypedDict](
*args: Unpack[T],
**kwargs: Unpack[K],
) -> NewProtocol[*[Member[c.name, int] for c in Iter[Attrs[K]]]]:
) -> NewProtocol[*Map(Member[c.name, int] for c in Iter[Attrs[K]])]:
raise NotImplementedError


Expand Down
6 changes: 3 additions & 3 deletions tests/test_dataclass_like.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ def _check_hero_init() -> None:
Callable[
typing.Params[
typing.Param[Literal["self"], T],
*[
*typing.Map(
typing.Param[
p.name,
p.type,
Expand All @@ -79,15 +79,15 @@ def _check_hero_init() -> None:
else Literal["keyword", "default"],
]
for p in typing.Iter[typing.Attrs[T]]
],
),
],
None,
],
Literal["ClassVar"],
]
type AddInit[T] = typing.NewProtocol[
InitFnType[T],
*[x for x in typing.Iter[typing.Members[T]]],
*typing.Map(x for x in typing.Iter[typing.Members[T]]),
]

"""
Expand Down
5 changes: 3 additions & 2 deletions tests/test_eval_call_with_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
GetArg,
IsAssignable,
Iter,
Map,
Members,
Param,
Params,
Expand Down Expand Up @@ -287,15 +288,15 @@ def func[T](x: C[T]) -> T: ...

type GetCallableMember[T, N: str] = GetArg[
tuple[
*[
*Map(
m.type
for m in Iter[Members[T]]
if (
IsAssignable[m.type, Callable]
or IsAssignable[m.type, GenericCallable]
)
and IsAssignable[m.name, N]
]
)
],
tuple,
Literal[0],
Expand Down
21 changes: 11 additions & 10 deletions tests/test_fastapilike_1.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from typemap_extensions import (
NewProtocol,
Iter,
Map,
Attrs,
IsAssignable,
GetAnnotations,
Expand Down Expand Up @@ -53,7 +54,7 @@ class _Default:
Callable[
Params[
Param[Literal["self"], Self],
*[
*Map(
Param[
p.name,
DropAnnotations[p.type],
Expand All @@ -65,7 +66,7 @@ class _Default:
else Literal["keyword"],
]
for p in Iter[Attrs[T]]
],
),
],
None,
],
Expand All @@ -76,13 +77,13 @@ class _Default:
InitFnType[T],
# TODO: mypy rejects this -- should it work?
# *Members[T],
*[t for t in Iter[Members[T]]],
*Map(t for t in Iter[Members[T]]),
]

# Strip `| None` from a type by iterating over its union components
# and filtering
type NotOptional[T] = Union[
*[x for x in Iter[FromUnion[T]] if not IsAssignable[x, None]]
*Map(x for x in Iter[FromUnion[T]] if not IsAssignable[x, None])
]

# Adjust an attribute type for use in Public below by dropping | None for
Expand All @@ -97,35 +98,35 @@ class _Default:
# Drop all the annotations, since this is for data getting returned to users
# from the DB, so we don't need default values.
type Public[T] = NewProtocol[
*[
*Map(
Member[p.name, FixPublicType[p.type], p.quals]
for p in Iter[Attrs[T]]
if not IsAssignable[Literal[PropQuals.HIDDEN], GetAnnotations[p.type]]
]
)
]

# Create takes everything but the primary key and preserves defaults
type Create[T] = NewProtocol[
*[
*Map(
Member[p.name, p.type, p.quals]
for p in Iter[Attrs[T]]
if not IsAssignable[Literal[PropQuals.PRIMARY], GetAnnotations[p.type]]
]
)
]


# Update takes everything but the primary key, but makes them all have
# None defaults
type Update[T] = NewProtocol[
*[
*Map(
Member[
p.name,
HasDefault[DropAnnotations[p.type] | None, None],
p.quals,
]
for p in Iter[Attrs[T]]
if not IsAssignable[Literal[PropQuals.PRIMARY], GetAnnotations[p.type]]
]
)
]


Expand Down
22 changes: 11 additions & 11 deletions tests/test_fastapilike_2.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ class Field[T: FieldArgs](typing.InitField[T]):
# Strip `| None` from a type by iterating over its union components
# and filtering
type NotOptional[T] = Union[
*[
*typing.Map(
x
for x in typing.Iter[typing.FromUnion[T]]
if not typing.IsAssignable[x, None]
]
)
]

# Adjust an attribute type for use in Public below by dropping | None for
Expand All @@ -58,7 +58,7 @@ class Field[T: FieldArgs](typing.InitField[T]):
# Drop all the annotations, since this is for data getting returned to users
# from the DB, so we don't need default values.
type Public[T] = typing.NewProtocol[
*[
*typing.Map(
typing.Member[
p.name,
FixPublicType[p.type, p.init],
Expand All @@ -68,7 +68,7 @@ class Field[T: FieldArgs](typing.InitField[T]):
if not typing.IsAssignable[
Literal[True], GetFieldItem[p.init, Literal["hidden"]]
]
]
)
]

# Begin PEP section: Automatically deriving FastAPI CRUD models
Expand All @@ -88,7 +88,7 @@ class Field[T: FieldArgs](typing.InitField[T]):

# Create takes everything but the primary key and preserves defaults
type Create[T] = typing.NewProtocol[
*[
*typing.Map(
typing.Member[
p.name,
p.type,
Expand All @@ -100,7 +100,7 @@ class Field[T: FieldArgs](typing.InitField[T]):
Literal[True],
GetFieldItem[p.init, Literal["primary_key"]],
]
]
)
]

"""
Expand All @@ -122,7 +122,7 @@ class Field[T: FieldArgs](typing.InitField[T]):
# Update takes everything but the primary key, but makes them all have
# None defaults
type Update[T] = typing.NewProtocol[
*[
*typing.Map(
typing.Member[
p.name,
p.type | None,
Expand All @@ -134,7 +134,7 @@ class Field[T: FieldArgs](typing.InitField[T]):
Literal[True],
GetFieldItem[p.init, Literal["primary_key"]],
]
]
)
]

##
Expand All @@ -145,7 +145,7 @@ class Field[T: FieldArgs](typing.InitField[T]):
Callable[
typing.Params[
typing.Param[Literal["self"], Self], # type: ignore[misc]
*[
*typing.Map(
typing.Param[
p.name,
p.type,
Expand All @@ -159,15 +159,15 @@ class Field[T: FieldArgs](typing.InitField[T]):
else Literal["keyword", "default"],
]
for p in typing.Iter[typing.Attrs[T]]
],
),
],
None,
],
Literal["ClassVar"],
]
type AddInit[T] = typing.NewProtocol[
InitFnType[T],
*[x for x in typing.Iter[typing.Members[T]]],
*typing.Map(x for x in typing.Iter[typing.Members[T]]),
]


Expand Down
7 changes: 4 additions & 3 deletions tests/test_qblike.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
BaseTypedDict,
NewProtocol,
Iter,
Map,
Attrs,
IsAssignable,
Member,
Expand All @@ -30,7 +31,7 @@ class Link[T]:


type PropsOnly[T] = NewProtocol[
*[p for p in Iter[Attrs[T]] if IsAssignable[p.type, Property]]
*Map(p for p in Iter[Attrs[T]] if IsAssignable[p.type, Property])
]

# Conditional type alias!
Expand All @@ -44,13 +45,13 @@ def select[K: BaseTypedDict](
/,
**kwargs: Unpack[K],
) -> NewProtocol[
*[
*Map(
Member[
c.name,
FilterLinks[GetMemberType[A, c.name]],
]
for c in Iter[Attrs[K]]
]
)
]:
raise NotImplementedError

Expand Down
8 changes: 4 additions & 4 deletions tests/test_qblike_2.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,13 @@ def select[ModelT, K: typing.BaseTypedDict](
**kwargs: Unpack[K],
) -> list[
typing.NewProtocol[
*[
*typing.Map(
typing.Member[
c.name,
ConvertField[typing.GetMemberType[ModelT, c.name]],
]
for c in typing.Iter[typing.Attrs[K]]
]
)
]
]:
raise NotImplementedError
Expand Down Expand Up @@ -112,11 +112,11 @@ def select[ModelT, K: typing.BaseTypedDict](

"""
type PropsOnly[T] = typing.NewProtocol[
*[
*typing.Map(
typing.Member[p.name, PointerArg[p.type]]
for p in typing.Iter[typing.Attrs[T]]
if typing.IsAssignable[p.type, Property]
]
)
]

"""
Expand Down
Loading
Loading