Skip to content
Merged
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
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,12 @@ See [pep.rst](pep.rst) for the PEP draft and [design-qs.rst](design-qs.rst) for
2. `$ cd typemap`
3. `$ uv sync`
4. `$ uv run pytest`

## Running the typechecker

If you have https://github.com/msullivan/mypy/tree/typemap active in a
venv, you can run it against at least some of the tests with
invocations like:
`mypy --python-version=3.14 tests/test_qblike_2.py`

Not all of them run cleanly yet though.
5 changes: 3 additions & 2 deletions pep.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1005,7 +1005,8 @@ as a literal type--all of these mechanisms lean very heavily on literal types.
for c in typing.Iter[typing.Attrs[K]]
]
]
]: ...
]:
raise NotImplementedError

ConvertField is our first type helper, and it is a conditional type
alias, which decides between two types based on a (limited)
Expand Down Expand Up @@ -1035,7 +1036,7 @@ grabs the argument to a ``Pointer``).

::

type PointerArg[T: Pointer] = typing.GetArg[T, Pointer, Literal[0]]
type PointerArg[T] = typing.GetArg[T, Pointer, Literal[0]]

``AdjustLink`` sticks a ``list`` around ``MultiLink``, using features
we've discussed already.
Expand Down
5 changes: 4 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ readme = "README.md"
requires-python = ">=3.14"
dependencies = []

[tool.setuptools.packages.find]
include = ["typemap", "typemap_extensions"]

[dependency-groups]
test = [
"pytest>=7.0",
Expand Down Expand Up @@ -68,7 +71,7 @@ extend-ignore = [
[tool.ruff]
line-length = 80
indent-width = 4
include = ["pyproject.toml", "typemap/**/*.py", "tests/**/*.py"]
include = ["pyproject.toml", "typemap/**/*.py", "typemap_extensions/**/*.py", "tests/**/*.py"]

[tool.ruff.format]
quote-style = "preserve"
4 changes: 2 additions & 2 deletions tests/format_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ def format_meth(name, meth):
code += f" {attr_name}: {attr_type_s}{eq}\n"

for name, attr in cls.__dict__.items():
if attr is typing._no_init_or_replace_init:
if attr is typing._no_init_or_replace_init: # type: ignore[attr-defined]
continue
if isinstance(attr, classmethod):
attr = inspect.unwrap(attr)
attr = inspect.unwrap(attr) # type: ignore[arg-type]
code += f" @classmethod\n"
elif isinstance(attr, staticmethod):
attr = inspect.unwrap(attr)
Expand Down
5 changes: 3 additions & 2 deletions tests/test_astlike_1.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
import typing

from typemap.type_eval import eval_call_with_types, eval_typing, TypeMapError
from typemap.typing import (
from typemap.typing import _BoolLiteral

from typemap_extensions import (
Attrs,
BaseTypedDict,
Bool,
Expand All @@ -15,7 +17,6 @@
Member,
NewProtocol,
RaiseError,
_BoolLiteral,
)


Expand Down
2 changes: 1 addition & 1 deletion tests/test_call.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from typing import Unpack

from typemap.type_eval import eval_call
from typemap.typing import (
from typemap_extensions import (
Attrs,
BaseTypedDict,
NewProtocol,
Expand Down
2 changes: 1 addition & 1 deletion tests/test_eval_call_with_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from typing import Callable, Generic, Literal, Self, TypeVar

from typemap.type_eval import eval_call_with_types
from typemap.typing import (
from typemap_extensions import (
GenericCallable,
GetArg,
GetName,
Expand Down
2 changes: 1 addition & 1 deletion tests/test_fastapilike_1.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from typing import Annotated, Callable, Literal, Union, Self

from typemap.type_eval import eval_typing
from typemap.typing import (
from typemap_extensions import (
NewProtocol,
Iter,
Attrs,
Expand Down
10 changes: 8 additions & 2 deletions tests/test_fastapilike_2.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@
TypedDict,
Never,
Self,
TYPE_CHECKING,
)

from typemap import typing
import typemap_extensions as typing


class FieldArgs(TypedDict, total=False):
Expand All @@ -25,7 +26,7 @@ class Field[T: FieldArgs](typing.InitField[T]):
####

# TODO: Should this go into the stdlib?
type GetFieldItem[T: typing.InitField, K] = typing.GetMemberType[
type GetFieldItem[T, K] = typing.GetMemberType[
typing.GetArg[T, typing.InitField, Literal[0]], K
]

Expand Down Expand Up @@ -207,6 +208,11 @@ class Hero:
secret_name: str = Field(hidden=True)


# Quick reveal_type test for running mypy against this
if TYPE_CHECKING:
pubhero: Public[Hero]
reveal_type(pubhero) # noqa
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?


#######

import textwrap
Expand Down
2 changes: 1 addition & 1 deletion tests/test_nplike.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from typing import Literal

from typemap import typing
import typemap_extensions as typing

import pytest

Expand Down
2 changes: 1 addition & 1 deletion tests/test_qblike.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
eval_call_with_types,
eval_typing,
)
from typemap.typing import (
from typemap_extensions import (
BaseTypedDict,
NewProtocol,
Iter,
Expand Down
21 changes: 17 additions & 4 deletions tests/test_qblike_2.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import textwrap

from typing import Literal, Unpack
from typing import Literal, Unpack, TYPE_CHECKING

from typemap.type_eval import eval_call, eval_typing
from typemap import typing
import typemap_extensions as typing

from . import format_helper

Expand Down Expand Up @@ -66,7 +66,8 @@ def select[ModelT, K: typing.BaseTypedDict](
for c in typing.Iter[typing.Attrs[K]]
]
]
]: ...
]:
raise NotImplementedError


"""ConvertField is our first type helper, and it is a conditional type
Expand Down Expand Up @@ -95,7 +96,7 @@ def select[ModelT, K: typing.BaseTypedDict](
grabs the argument to a ``Pointer``).

"""
type PointerArg[T: Pointer] = typing.GetArg[T, Pointer, Literal[0]]
type PointerArg[T] = typing.GetArg[T, Pointer, Literal[0]]

"""
``AdjustLink`` sticks a ``list`` around ``MultiLink``, using features
Expand Down Expand Up @@ -151,6 +152,18 @@ class User:
posts: MultiLink[Post]


def test_qblike_typing_only_1() -> None:
# Quick reveal_type test for running mypy against this
if TYPE_CHECKING:
_test_select = select(
Post,
title=True,
comments=True,
author=True,
)
reveal_type(_test_select) # noqa
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?



def test_qblike2_1():
ret = eval_call(
select,
Expand Down
2 changes: 1 addition & 1 deletion tests/test_qblike_3.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
)

from typemap.type_eval import eval_call_with_types, eval_typing
from typemap.typing import (
from typemap_extensions import (
Attrs,
Bool,
Length,
Expand Down
2 changes: 1 addition & 1 deletion tests/test_schemalike.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from typing import Callable, Literal

from typemap.type_eval import eval_typing
from typemap.typing import (
from typemap_extensions import (
NewProtocol,
Iter,
Attrs,
Expand Down
2 changes: 1 addition & 1 deletion tests/test_type_dir.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from typing import Literal, Never, TypeVar, TypedDict, Union, ReadOnly

from typemap.type_eval import eval_typing
from typemap.typing import (
from typemap_extensions import (
Attrs,
FromUnion,
GetArg,
Expand Down
7 changes: 4 additions & 3 deletions tests/test_type_eval.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
import pytest

from typemap.type_eval import eval_typing
from typemap.typing import (
from typemap.typing import _BoolLiteral

from typemap_extensions import (
Attrs,
Bool,
FromUnion,
Expand All @@ -44,7 +46,6 @@
SpecialFormEllipsis,
StrConcat,
Uppercase,
_BoolLiteral,
)

from . import format_helper
Expand Down Expand Up @@ -1675,7 +1676,7 @@ def test_type_eval_annotated_04():
##############
# RaiseError tests

from typemap.typing import RaiseError
from typemap_extensions import RaiseError
from typemap.type_eval import TypeMapError


Expand Down
2 changes: 1 addition & 1 deletion typemap/type_eval/_eval_operators.py
Original file line number Diff line number Diff line change
Expand Up @@ -577,7 +577,7 @@ def _ann(x):

# TODO: Is doing the tuple for staticmethod/classmethod legit?
# Putting a list in makes it unhashable...
f: typing.Any
f: typing.Any # type: ignore[annotation-unchecked]
if isinstance(func, staticmethod):
f = staticmethod[tuple[*params], ret]
elif isinstance(func, classmethod):
Expand Down
8 changes: 8 additions & 0 deletions typemap_extensions/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# mypy: follow-imports=skip

# The canonical place to use typemap stuff from right now is
# typemap_extensions. The point of this is to split the internals
# from what the tests import, so that type_eval can look at the real
# definitions while tests don't see that, and could have mypy stubs
# injected instead.
from typemap.typing import * # noqa: F403
1 change: 1 addition & 0 deletions typemap_extensions/__init__.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from _typeshed.typemap import *