]> git.ipfire.org Git - thirdparty/fastapi/sqlmodel.git/commitdiff
👷 Replace `mypy` with `ty` in precommit (#1806)
authorSofie Van Landeghem <svlandeg@users.noreply.github.com>
Fri, 3 Apr 2026 11:30:27 +0000 (13:30 +0200)
committerGitHub <noreply@github.com>
Fri, 3 Apr 2026 11:30:27 +0000 (13:30 +0200)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
.pre-commit-config.yaml
pyproject.toml
scripts/generate_select.py
scripts/lint.sh
sqlmodel/main.py
sqlmodel/sql/_expression_select_cls.py
sqlmodel/sql/_expression_select_gen.py
sqlmodel/sql/_expression_select_gen.py.jinja2
sqlmodel/sql/expression.py
sqlmodel/sql/sqltypes.py
uv.lock

index 5063e81fef236aa76e4707cf948597c0bdafb6f0..9493664b78cb53cc38922e0732a7e09a564289ce 100644 (file)
@@ -28,9 +28,9 @@ repos:
         language: unsupported
         types: [python]
 
-      - id: local-mypy
-        name: mypy check
-        entry: uv run mypy sqlmodel tests/test_select_typing.py
+      - id: local-ty
+        name: ty check
+        entry: uv run ty check sqlmodel tests/test_select_typing.py
         require_serial: true
         language: unsupported
         pass_filenames: false
index e0819ff8c54f6e1f330fd2e21ab4851de409c0a7..3bc56a16a12d87ead52e031e5d1f6eb1d9086941 100644 (file)
@@ -82,9 +82,9 @@ tests = [
     "fastapi >=0.128.0",
     "httpx >=0.28.1",
     "jinja2 >=3.1.6",
-    "mypy >=1.19.1",
     "pytest >=7.0.1",
     "ruff >=0.15.6",
+    "ty>=0.0.25",
     "typing-extensions >=4.15.0",
 ]
 
@@ -125,16 +125,6 @@ exclude_lines = [
 [tool.coverage.html]
 show_contexts = true
 
-[tool.mypy]
-strict = true
-exclude = "sqlmodel.sql._expression_select_gen"
-
-[[tool.mypy.overrides]]
-module = "docs_src.*"
-disallow_incomplete_defs = false
-disallow_untyped_defs = false
-disallow_untyped_calls = false
-
 [tool.ruff.lint]
 select = [
     "E",  # pycodestyle errors
@@ -161,3 +151,6 @@ known-third-party = ["sqlmodel", "sqlalchemy", "pydantic", "fastapi"]
 [tool.ruff.lint.pyupgrade]
 # Preserve types, even if a file imports `from __future__ import annotations`.
 keep-runtime-typing = true
+
+[tool.ty.terminal]
+error-on-warning = true
index cbb842b3673bd0389d27170da59468bb50afd7f8..66729c69dc994cfacaa9543b2a1d34a76733b4d4 100644 (file)
@@ -37,7 +37,7 @@ for total_args in range(2, number_of_types + 1):
             else:
                 t_type = f"_T{i}"
                 t_var = f"_TCCA[{t_type}]"
-                arg = Arg(name=f"__ent{i}", annotation=t_var)
+                arg = Arg(name=f"ent{i}", annotation=t_var)
                 ret_type = t_type
             args.append(arg)
             return_types.append(ret_type)
index e4a7b5bea72b3d600c8e2d8ea595f8b13cafa5a5..9b2366d226ac6a38507876a509a1884d6c0dce83 100755 (executable)
@@ -3,7 +3,7 @@
 set -e
 set -x
 
-mypy sqlmodel
-mypy tests/test_select_typing.py
+ty check sqlmodel
+ty check tests/test_select_typing.py
 ruff check sqlmodel tests docs_src scripts
 ruff format sqlmodel tests docs_src scripts --check
index 17d64e8ffbf985d02d071767967ed5a8e1f50a6b..9a1a676775a7cde7b36a9b475016fa142dd957d2 100644 (file)
@@ -3,7 +3,6 @@ from __future__ import annotations
 import builtins
 import ipaddress
 import uuid
-import weakref
 from collections.abc import Callable, Mapping, Sequence, Set
 from dataclasses import dataclass
 from datetime import date, datetime, time, timedelta
@@ -52,7 +51,7 @@ from sqlalchemy.sql.schema import MetaData
 from sqlalchemy.sql.sqltypes import LargeBinary, Time, Uuid
 from typing_extensions import deprecated
 
-from ._compat import (  # type: ignore[attr-defined]
+from ._compat import (
     PYDANTIC_MINOR_VERSION,
     BaseConfig,
     ModelMetaclass,
@@ -101,7 +100,7 @@ def __dataclass_transform__(
     return lambda a: a
 
 
-class FieldInfo(PydanticFieldInfo):  # type: ignore[misc]
+class FieldInfo(PydanticFieldInfo):  # ty: ignore[subclass-of-final-class]
     # mypy - ignore that PydanticFieldInfo is @final
     def __init__(self, default: Any = Undefined, **kwargs: Any) -> None:
         primary_key = kwargs.pop("primary_key", False)
@@ -177,7 +176,7 @@ class RelationshipInfo(Representation):
         cascade_delete: bool | None = False,
         passive_deletes: bool | Literal["all"] | None = False,
         link_model: Any | None = None,
-        sa_relationship: RelationshipProperty | None = None,  # type: ignore
+        sa_relationship: RelationshipProperty | None = None,
         sa_relationship_args: Sequence[Any] | None = None,
         sa_relationship_kwargs: Mapping[str, Any] | None = None,
     ) -> None:
@@ -398,7 +397,7 @@ def Field(
     nullable: bool | UndefinedType = Undefined,
     index: bool | UndefinedType = Undefined,
     sa_type: type[Any] | UndefinedType = Undefined,
-    sa_column: Column | UndefinedType = Undefined,  # type: ignore
+    sa_column: Column | UndefinedType = Undefined,
     sa_column_args: Sequence[Any] | UndefinedType = Undefined,
     sa_column_kwargs: Mapping[str, Any] | UndefinedType = Undefined,
     schema_extra: dict[str, Any] | None = None,
@@ -525,13 +524,13 @@ class SQLModelMetaclass(ModelMetaclass, DeclarativeMeta):
     model_fields: ClassVar[dict[str, FieldInfo]]
 
     # Replicate SQLAlchemy
-    def __setattr__(cls, name: str, value: Any) -> None:
+    def __setattr__(cls, name: str, value: Any) -> None:  # ty: ignore[invalid-method-override]
         if is_table_model_class(cls):
             DeclarativeMeta.__setattr__(cls, name, value)
         else:
             super().__setattr__(name, value)
 
-    def __delattr__(cls, name: str) -> None:
+    def __delattr__(cls, name: str) -> None:  # ty: ignore[invalid-method-override]
         if is_table_model_class(cls):
             DeclarativeMeta.__delattr__(cls, name)
         else:
@@ -609,10 +608,10 @@ class SQLModelMetaclass(ModelMetaclass, DeclarativeMeta):
             # This could be done by reading new_cls.model_config['table'] in FastAPI, but
             # that's very specific about SQLModel, so let's have another config that
             # other future tools based on Pydantic can use.
-            new_cls.model_config["read_from_attributes"] = True  # type: ignore[typeddict-unknown-key]
+            new_cls.model_config["read_from_attributes"] = True  # ty: ignore[invalid-key]
             # For compatibility with older versions
             # TODO: remove this in the future
-            new_cls.model_config["read_with_orm_mode"] = True  # type: ignore[typeddict-unknown-key]
+            new_cls.model_config["read_with_orm_mode"] = True  # ty: ignore[invalid-key]
 
         config_registry = get_config("registry")
         if config_registry is not Undefined:
@@ -649,7 +648,7 @@ class SQLModelMetaclass(ModelMetaclass, DeclarativeMeta):
                     # Plain forward references, for models not yet defined, are not
                     # handled well by SQLAlchemy without Mapped, so, wrap the
                     # annotations in Mapped here
-                    cls.__annotations__[rel_name] = Mapped[ann]  # type: ignore[valid-type]
+                    cls.__annotations__[rel_name] = Mapped[ann]
                 relationship_to = get_relationship_to(
                     name=rel_name, rel_info=rel_info, annotation=ann
                 )
@@ -738,7 +737,7 @@ def get_sqlalchemy_type(field: Any) -> Any:
     raise ValueError(f"{type_} has no matching SQLAlchemy type")
 
 
-def get_column_from_field(field: Any) -> Column:  # type: ignore
+def get_column_from_field(field: Any) -> Column:
     field_info = field
     sa_column = _get_sqlmodel_field_value(field_info, "sa_column", Undefined)
     if isinstance(sa_column, Column):
@@ -773,7 +772,7 @@ def get_column_from_field(field: Any) -> Column:  # type: ignore
         assert isinstance(foreign_key, str)
         assert isinstance(ondelete_value, (str, type(None)))  # for typing
         args.append(ForeignKey(foreign_key, ondelete=ondelete_value))
-    kwargs = {
+    kwargs: dict[str, Any] = {
         "primary_key": primary_key,
         "nullable": nullable,
         "index": index,
@@ -797,8 +796,6 @@ def get_column_from_field(field: Any) -> Column:  # type: ignore
     return Column(sa_type, *args, **kwargs)
 
 
-class_registry = weakref.WeakValueDictionary()  # type: ignore
-
 default_registry = registry()
 
 _TSQLModel = TypeVar("_TSQLModel", bound="SQLModel")
@@ -852,7 +849,7 @@ class SQLModel(BaseModel, metaclass=SQLModelMetaclass, registry=default_registry
             return
         else:
             # Set in SQLAlchemy, before Pydantic to trigger events and updates
-            if is_table_model_class(self.__class__) and is_instrumented(self, name):  # type: ignore[no-untyped-call]
+            if is_table_model_class(self.__class__) and is_instrumented(self, name):
                 set_attribute(self, name, value)
             # Set in Pydantic model to trigger possible validation changes, only for
             # non relationship values
@@ -872,7 +869,7 @@ class SQLModel(BaseModel, metaclass=SQLModelMetaclass, registry=default_registry
         return cls.__name__.lower()
 
     @classmethod
-    def model_validate(  # type: ignore[override]
+    def model_validate(  # ty: ignore[invalid-method-override]
         cls: type[_TSQLModel],
         obj: Any,
         *,
index 1229c229353337d70559f691b587da69fa9568f3..124929d2c39ce36f72607be3f5b67f9d6ea83ee9 100644 (file)
@@ -20,13 +20,13 @@ class SelectBase(_Select[tuple[_T]]):
         """Return a new `Select` construct with the given expression added to
         its `WHERE` clause, joined to the existing clause via `AND`, if any.
         """
-        return super().where(*whereclause)  # type: ignore[arg-type]
+        return super().where(*whereclause)
 
     def having(self, *having: _ColumnExpressionArgument[bool] | bool) -> Self:
         """Return a new `Select` construct with the given expression added to
         its `HAVING` clause, joined to the existing clause via `AND`, if any.
         """
-        return super().having(*having)  # type: ignore[arg-type]
+        return super().having(*having)
 
 
 class Select(SelectBase[_T]):
index 83d934c68ba07fb863446f7149e93960588e462e..a1c85c71c963c39f8a7d2b981953635bb119c0a7 100644 (file)
@@ -29,9 +29,9 @@ _TCCA = TypedColumnsClauseRole[_T] | SQLCoreOperations[_T] | type[_T]
 
 _TScalar_0 = TypeVar(
     "_TScalar_0",
-    Column,  # type: ignore
-    Sequence,  # type: ignore
-    Mapping,  # type: ignore
+    Column,
+    Sequence,
+    Mapping,
     UUID,
     datetime,
     float,
@@ -47,9 +47,9 @@ _T0 = TypeVar("_T0")
 
 _TScalar_1 = TypeVar(
     "_TScalar_1",
-    Column,  # type: ignore
-    Sequence,  # type: ignore
-    Mapping,  # type: ignore
+    Column,
+    Sequence,
+    Mapping,
     UUID,
     datetime,
     float,
@@ -65,9 +65,9 @@ _T1 = TypeVar("_T1")
 
 _TScalar_2 = TypeVar(
     "_TScalar_2",
-    Column,  # type: ignore
-    Sequence,  # type: ignore
-    Mapping,  # type: ignore
+    Column,
+    Sequence,
+    Mapping,
     UUID,
     datetime,
     float,
@@ -83,9 +83,9 @@ _T2 = TypeVar("_T2")
 
 _TScalar_3 = TypeVar(
     "_TScalar_3",
-    Column,  # type: ignore
-    Sequence,  # type: ignore
-    Mapping,  # type: ignore
+    Column,
+    Sequence,
+    Mapping,
     UUID,
     datetime,
     float,
@@ -103,257 +103,284 @@ _T3 = TypeVar("_T3")
 
 
 @overload
-def select(__ent0: _TCCA[_T0]) -> SelectOfScalar[_T0]: ...
+def select(ent0: _TCCA[_T0], /) -> SelectOfScalar[_T0]: ...
 
 
 @overload
-def select(__ent0: _TScalar_0) -> SelectOfScalar[_TScalar_0]:  # type: ignore
-    ...
+def select(ent0: _TScalar_0, /) -> SelectOfScalar[_TScalar_0]: ...
 
 
 # Generated overloads start
 
 
 @overload
-def select(  # type: ignore
-    __ent0: _TCCA[_T0],
-    __ent1: _TCCA[_T1],
+def select(
+    ent0: _TCCA[_T0],
+    ent1: _TCCA[_T1],
+    /,
 ) -> Select[tuple[_T0, _T1]]: ...
 
 
 @overload
-def select(  # type: ignore
-    __ent0: _TCCA[_T0],
+def select(
+    ent0: _TCCA[_T0],
     entity_1: _TScalar_1,
+    /,
 ) -> Select[tuple[_T0, _TScalar_1]]: ...
 
 
 @overload
-def select(  # type: ignore
+def select(
     entity_0: _TScalar_0,
-    __ent1: _TCCA[_T1],
+    ent1: _TCCA[_T1],
+    /,
 ) -> Select[tuple[_TScalar_0, _T1]]: ...
 
 
 @overload
-def select(  # type: ignore
+def select(
     entity_0: _TScalar_0,
     entity_1: _TScalar_1,
+    /,
 ) -> Select[tuple[_TScalar_0, _TScalar_1]]: ...
 
 
 @overload
-def select(  # type: ignore
-    __ent0: _TCCA[_T0],
-    __ent1: _TCCA[_T1],
-    __ent2: _TCCA[_T2],
+def select(
+    ent0: _TCCA[_T0],
+    ent1: _TCCA[_T1],
+    ent2: _TCCA[_T2],
+    /,
 ) -> Select[tuple[_T0, _T1, _T2]]: ...
 
 
 @overload
-def select(  # type: ignore
-    __ent0: _TCCA[_T0],
-    __ent1: _TCCA[_T1],
+def select(
+    ent0: _TCCA[_T0],
+    ent1: _TCCA[_T1],
     entity_2: _TScalar_2,
+    /,
 ) -> Select[tuple[_T0, _T1, _TScalar_2]]: ...
 
 
 @overload
-def select(  # type: ignore
-    __ent0: _TCCA[_T0],
+def select(
+    ent0: _TCCA[_T0],
     entity_1: _TScalar_1,
-    __ent2: _TCCA[_T2],
+    ent2: _TCCA[_T2],
+    /,
 ) -> Select[tuple[_T0, _TScalar_1, _T2]]: ...
 
 
 @overload
-def select(  # type: ignore
-    __ent0: _TCCA[_T0],
+def select(
+    ent0: _TCCA[_T0],
     entity_1: _TScalar_1,
     entity_2: _TScalar_2,
+    /,
 ) -> Select[tuple[_T0, _TScalar_1, _TScalar_2]]: ...
 
 
 @overload
-def select(  # type: ignore
+def select(
     entity_0: _TScalar_0,
-    __ent1: _TCCA[_T1],
-    __ent2: _TCCA[_T2],
+    ent1: _TCCA[_T1],
+    ent2: _TCCA[_T2],
+    /,
 ) -> Select[tuple[_TScalar_0, _T1, _T2]]: ...
 
 
 @overload
-def select(  # type: ignore
+def select(
     entity_0: _TScalar_0,
-    __ent1: _TCCA[_T1],
+    ent1: _TCCA[_T1],
     entity_2: _TScalar_2,
+    /,
 ) -> Select[tuple[_TScalar_0, _T1, _TScalar_2]]: ...
 
 
 @overload
-def select(  # type: ignore
+def select(
     entity_0: _TScalar_0,
     entity_1: _TScalar_1,
-    __ent2: _TCCA[_T2],
+    ent2: _TCCA[_T2],
+    /,
 ) -> Select[tuple[_TScalar_0, _TScalar_1, _T2]]: ...
 
 
 @overload
-def select(  # type: ignore
+def select(
     entity_0: _TScalar_0,
     entity_1: _TScalar_1,
     entity_2: _TScalar_2,
+    /,
 ) -> Select[tuple[_TScalar_0, _TScalar_1, _TScalar_2]]: ...
 
 
 @overload
-def select(  # type: ignore
-    __ent0: _TCCA[_T0],
-    __ent1: _TCCA[_T1],
-    __ent2: _TCCA[_T2],
-    __ent3: _TCCA[_T3],
+def select(
+    ent0: _TCCA[_T0],
+    ent1: _TCCA[_T1],
+    ent2: _TCCA[_T2],
+    ent3: _TCCA[_T3],
+    /,
 ) -> Select[tuple[_T0, _T1, _T2, _T3]]: ...
 
 
 @overload
-def select(  # type: ignore
-    __ent0: _TCCA[_T0],
-    __ent1: _TCCA[_T1],
-    __ent2: _TCCA[_T2],
+def select(
+    ent0: _TCCA[_T0],
+    ent1: _TCCA[_T1],
+    ent2: _TCCA[_T2],
     entity_3: _TScalar_3,
+    /,
 ) -> Select[tuple[_T0, _T1, _T2, _TScalar_3]]: ...
 
 
 @overload
-def select(  # type: ignore
-    __ent0: _TCCA[_T0],
-    __ent1: _TCCA[_T1],
+def select(
+    ent0: _TCCA[_T0],
+    ent1: _TCCA[_T1],
     entity_2: _TScalar_2,
-    __ent3: _TCCA[_T3],
+    ent3: _TCCA[_T3],
+    /,
 ) -> Select[tuple[_T0, _T1, _TScalar_2, _T3]]: ...
 
 
 @overload
-def select(  # type: ignore
-    __ent0: _TCCA[_T0],
-    __ent1: _TCCA[_T1],
+def select(
+    ent0: _TCCA[_T0],
+    ent1: _TCCA[_T1],
     entity_2: _TScalar_2,
     entity_3: _TScalar_3,
+    /,
 ) -> Select[tuple[_T0, _T1, _TScalar_2, _TScalar_3]]: ...
 
 
 @overload
-def select(  # type: ignore
-    __ent0: _TCCA[_T0],
+def select(
+    ent0: _TCCA[_T0],
     entity_1: _TScalar_1,
-    __ent2: _TCCA[_T2],
-    __ent3: _TCCA[_T3],
+    ent2: _TCCA[_T2],
+    ent3: _TCCA[_T3],
+    /,
 ) -> Select[tuple[_T0, _TScalar_1, _T2, _T3]]: ...
 
 
 @overload
-def select(  # type: ignore
-    __ent0: _TCCA[_T0],
+def select(
+    ent0: _TCCA[_T0],
     entity_1: _TScalar_1,
-    __ent2: _TCCA[_T2],
+    ent2: _TCCA[_T2],
     entity_3: _TScalar_3,
+    /,
 ) -> Select[tuple[_T0, _TScalar_1, _T2, _TScalar_3]]: ...
 
 
 @overload
-def select(  # type: ignore
-    __ent0: _TCCA[_T0],
+def select(
+    ent0: _TCCA[_T0],
     entity_1: _TScalar_1,
     entity_2: _TScalar_2,
-    __ent3: _TCCA[_T3],
+    ent3: _TCCA[_T3],
+    /,
 ) -> Select[tuple[_T0, _TScalar_1, _TScalar_2, _T3]]: ...
 
 
 @overload
-def select(  # type: ignore
-    __ent0: _TCCA[_T0],
+def select(
+    ent0: _TCCA[_T0],
     entity_1: _TScalar_1,
     entity_2: _TScalar_2,
     entity_3: _TScalar_3,
+    /,
 ) -> Select[tuple[_T0, _TScalar_1, _TScalar_2, _TScalar_3]]: ...
 
 
 @overload
-def select(  # type: ignore
+def select(
     entity_0: _TScalar_0,
-    __ent1: _TCCA[_T1],
-    __ent2: _TCCA[_T2],
-    __ent3: _TCCA[_T3],
+    ent1: _TCCA[_T1],
+    ent2: _TCCA[_T2],
+    ent3: _TCCA[_T3],
+    /,
 ) -> Select[tuple[_TScalar_0, _T1, _T2, _T3]]: ...
 
 
 @overload
-def select(  # type: ignore
+def select(
     entity_0: _TScalar_0,
-    __ent1: _TCCA[_T1],
-    __ent2: _TCCA[_T2],
+    ent1: _TCCA[_T1],
+    ent2: _TCCA[_T2],
     entity_3: _TScalar_3,
+    /,
 ) -> Select[tuple[_TScalar_0, _T1, _T2, _TScalar_3]]: ...
 
 
 @overload
-def select(  # type: ignore
+def select(
     entity_0: _TScalar_0,
-    __ent1: _TCCA[_T1],
+    ent1: _TCCA[_T1],
     entity_2: _TScalar_2,
-    __ent3: _TCCA[_T3],
+    ent3: _TCCA[_T3],
+    /,
 ) -> Select[tuple[_TScalar_0, _T1, _TScalar_2, _T3]]: ...
 
 
 @overload
-def select(  # type: ignore
+def select(
     entity_0: _TScalar_0,
-    __ent1: _TCCA[_T1],
+    ent1: _TCCA[_T1],
     entity_2: _TScalar_2,
     entity_3: _TScalar_3,
+    /,
 ) -> Select[tuple[_TScalar_0, _T1, _TScalar_2, _TScalar_3]]: ...
 
 
 @overload
-def select(  # type: ignore
+def select(
     entity_0: _TScalar_0,
     entity_1: _TScalar_1,
-    __ent2: _TCCA[_T2],
-    __ent3: _TCCA[_T3],
+    ent2: _TCCA[_T2],
+    ent3: _TCCA[_T3],
+    /,
 ) -> Select[tuple[_TScalar_0, _TScalar_1, _T2, _T3]]: ...
 
 
 @overload
-def select(  # type: ignore
+def select(
     entity_0: _TScalar_0,
     entity_1: _TScalar_1,
-    __ent2: _TCCA[_T2],
+    ent2: _TCCA[_T2],
     entity_3: _TScalar_3,
+    /,
 ) -> Select[tuple[_TScalar_0, _TScalar_1, _T2, _TScalar_3]]: ...
 
 
 @overload
-def select(  # type: ignore
+def select(
     entity_0: _TScalar_0,
     entity_1: _TScalar_1,
     entity_2: _TScalar_2,
-    __ent3: _TCCA[_T3],
+    ent3: _TCCA[_T3],
+    /,
 ) -> Select[tuple[_TScalar_0, _TScalar_1, _TScalar_2, _T3]]: ...
 
 
 @overload
-def select(  # type: ignore
+def select(
     entity_0: _TScalar_0,
     entity_1: _TScalar_1,
     entity_2: _TScalar_2,
     entity_3: _TScalar_3,
+    /,
 ) -> Select[tuple[_TScalar_0, _TScalar_1, _TScalar_2, _TScalar_3]]: ...
 
 
 # Generated overloads end
 
 
-def select(*entities: Any) -> Select | SelectOfScalar:  # type: ignore
+def select(*entities: Any) -> Select | SelectOfScalar:
     if len(entities) == 1:
         return SelectOfScalar(*entities)
     return Select(*entities)
index 2ce54cb2faf12e8d5f6dee27671803b8627444e6..648785dec135a5bb16c5b289a5e9ba330438c9c7 100644 (file)
@@ -28,9 +28,9 @@ _TCCA = TypedColumnsClauseRole[_T] | SQLCoreOperations[_T] | type[_T]
 {% for i in range(number_of_types) %}
 _TScalar_{{ i }} = TypeVar(
     "_TScalar_{{ i }}",
-    Column,  # type: ignore
-    Sequence,  # type: ignore
-    Mapping,  # type: ignore
+    Column,
+    Sequence,
+    Mapping,
     UUID,
     datetime,
     float,
@@ -48,12 +48,11 @@ _T{{ i }} = TypeVar("_T{{ i }}")
 # Generated TypeVars end
 
 @overload
-def select(__ent0: _TCCA[_T0]) -> SelectOfScalar[_T0]: ...
+def select(ent0: _TCCA[_T0], /) -> SelectOfScalar[_T0]: ...
 
 
 @overload
-def select(__ent0: _TScalar_0) -> SelectOfScalar[_TScalar_0]:  # type: ignore
-    ...
+def select(ent0: _TScalar_0, /) -> SelectOfScalar[_TScalar_0]: ...
 
 
 # Generated overloads start
@@ -61,8 +60,8 @@ def select(__ent0: _TScalar_0) -> SelectOfScalar[_TScalar_0]:  # type: ignore
 {% for signature in signatures %}
 
 @overload
-def select(  # type: ignore
-    {% for arg in signature[0] %}{{ arg.name }}: {{ arg.annotation }}, {% endfor %}
+def select(
+    {% for arg in signature[0] %}{{ arg.name }}: {{ arg.annotation }}, {% endfor %}/,
     ) -> Select[tuple[{%for ret in signature[1] %}{{ ret }} {% if not loop.last %}, {% endif %}{% endfor %}]]: ...
 
 {% endfor %}
@@ -70,7 +69,7 @@ def select(  # type: ignore
 # Generated overloads end
 
 
-def select(*entities: Any) -> Select | SelectOfScalar:  # type: ignore
+def select(*entities: Any) -> Select | SelectOfScalar:
     if len(entities) == 1:
         return SelectOfScalar(*entities)
     return Select(*entities)
index 249d6c461a56cf3f2a239306b2ccf4d6bdfc45c4..92d772a8835a82eb824283c1da989b21823bd097 100644 (file)
@@ -48,30 +48,30 @@ _TypeEngineArgument = type[TypeEngine[_T]] | TypeEngine[_T]
 
 
 def all_(expr: _ColumnExpressionArgument[_T] | _T) -> CollectionAggregate[bool]:
-    return sqlalchemy.all_(expr)  # type: ignore[arg-type]
+    return sqlalchemy.all_(expr)  # ty: ignore[invalid-argument-type]
 
 
 def and_(
     initial_clause: Literal[True] | _ColumnExpressionArgument[bool] | bool,
     *clauses: _ColumnExpressionArgument[bool] | bool,
 ) -> ColumnElement[bool]:
-    return sqlalchemy.and_(initial_clause, *clauses)  # type: ignore[arg-type]
+    return sqlalchemy.and_(initial_clause, *clauses)  # ty: ignore[invalid-argument-type]
 
 
 def any_(expr: _ColumnExpressionArgument[_T] | _T) -> CollectionAggregate[bool]:
-    return sqlalchemy.any_(expr)  # type: ignore[arg-type]
+    return sqlalchemy.any_(expr)  # ty: ignore[invalid-argument-type]
 
 
 def asc(
     column: _ColumnExpressionOrStrLabelArgument[_T] | _T,
 ) -> UnaryExpression[_T]:
-    return sqlalchemy.asc(column)  # type: ignore[arg-type]
+    return sqlalchemy.asc(column)  # ty: ignore[invalid-argument-type]
 
 
 def collate(
     expression: _ColumnExpressionArgument[str] | str, collation: str
 ) -> BinaryExpression[str]:
-    return sqlalchemy.collate(expression, collation)  # type: ignore[arg-type]
+    return sqlalchemy.collate(expression, collation)  # ty: ignore[invalid-argument-type]
 
 
 def between(
@@ -84,7 +84,7 @@ def between(
 
 
 def not_(clause: _ColumnExpressionArgument[_T] | _T) -> ColumnElement[_T]:
-    return sqlalchemy.not_(clause)  # type: ignore[arg-type]
+    return sqlalchemy.not_(clause)  # ty: ignore[no-matching-overload]
 
 
 def case(
@@ -92,7 +92,7 @@ def case(
     value: Any | None = None,
     else_: Any | None = None,
 ) -> Case[Any]:
-    return sqlalchemy.case(*whens, value=value, else_=else_)  # type: ignore[arg-type]
+    return sqlalchemy.case(*whens, value=value, else_=else_)  # ty: ignore[invalid-argument-type]
 
 
 def cast(
@@ -112,15 +112,15 @@ def try_cast(
 def desc(
     column: _ColumnExpressionOrStrLabelArgument[_T] | _T,
 ) -> UnaryExpression[_T]:
-    return sqlalchemy.desc(column)  # type: ignore[arg-type]
+    return sqlalchemy.desc(column)  # ty: ignore[invalid-argument-type]
 
 
 def distinct(expr: _ColumnExpressionArgument[_T] | _T) -> UnaryExpression[_T]:
-    return sqlalchemy.distinct(expr)  # type: ignore[arg-type]
+    return sqlalchemy.distinct(expr)  # ty: ignore[invalid-argument-type]
 
 
 def bitwise_not(expr: _ColumnExpressionArgument[_T] | _T) -> UnaryExpression[_T]:
-    return sqlalchemy.bitwise_not(expr)  # type: ignore[arg-type]
+    return sqlalchemy.bitwise_not(expr)  # ty: ignore[invalid-argument-type]
 
 
 def extract(field: str, expr: _ColumnExpressionArgument[Any] | Any) -> Extract:
@@ -130,7 +130,7 @@ def extract(field: str, expr: _ColumnExpressionArgument[Any] | Any) -> Extract:
 def funcfilter(
     func: FunctionElement[_T], *criterion: _ColumnExpressionArgument[bool] | bool
 ) -> FunctionFilter[_T]:
-    return sqlalchemy.funcfilter(func, *criterion)  # type: ignore[arg-type]
+    return sqlalchemy.funcfilter(func, *criterion)  # ty: ignore[invalid-argument-type]
 
 
 def label(
@@ -138,24 +138,24 @@ def label(
     element: _ColumnExpressionArgument[_T] | _T,
     type_: Optional["_TypeEngineArgument[_T]"] = None,
 ) -> Label[_T]:
-    return sqlalchemy.label(name, element, type_=type_)  # type: ignore[arg-type]
+    return sqlalchemy.label(name, element, type_=type_)  # ty: ignore[invalid-argument-type]
 
 
 def nulls_first(
     column: _ColumnExpressionArgument[_T] | _T,
 ) -> UnaryExpression[_T]:
-    return sqlalchemy.nulls_first(column)  # type: ignore[arg-type]
+    return sqlalchemy.nulls_first(column)  # ty: ignore[invalid-argument-type]
 
 
 def nulls_last(column: _ColumnExpressionArgument[_T] | _T) -> UnaryExpression[_T]:
-    return sqlalchemy.nulls_last(column)  # type: ignore[arg-type]
+    return sqlalchemy.nulls_last(column)  # ty: ignore[invalid-argument-type]
 
 
 def or_(
     initial_clause: Literal[False] | _ColumnExpressionArgument[bool] | bool,
     *clauses: _ColumnExpressionArgument[bool] | bool,
 ) -> ColumnElement[bool]:
-    return sqlalchemy.or_(initial_clause, *clauses)  # type: ignore[arg-type]
+    return sqlalchemy.or_(initial_clause, *clauses)  # ty: ignore[invalid-argument-type]
 
 
 def over(
index 512daacbabf77b921146ba6de128048b236b37fa..3119b1b6244341bd55c6f804cf529dbe647cb249 100644 (file)
@@ -4,7 +4,7 @@ from sqlalchemy import types
 from sqlalchemy.engine.interfaces import Dialect
 
 
-class AutoString(types.TypeDecorator):  # type: ignore
+class AutoString(types.TypeDecorator):
     impl = types.String
     cache_ok = True
     mysql_default_length = 255
diff --git a/uv.lock b/uv.lock
index f5973781a9d43df756bc3d3494de41eab04a6aa8..16d0fc606b22ebd105673e29122f553561d8cbc2 100644 (file)
--- a/uv.lock
+++ b/uv.lock
@@ -1126,64 +1126,6 @@ wheels = [
     { url = "https://files.pythonhosted.org/packages/32/28/79f0f8de97cce916d5ae88a7bee1ad724855e83e6019c0b4d5b3fabc80f3/mkdocstrings_python-2.0.3-py3-none-any.whl", hash = "sha256:0b83513478bdfd803ff05aa43e9b1fca9dd22bcd9471f09ca6257f009bc5ee12", size = 104779, upload-time = "2026-02-20T10:38:34.517Z" },
 ]
 
-[[package]]
-name = "mypy"
-version = "1.20.0"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
-    { name = "librt", marker = "platform_python_implementation != 'PyPy'" },
-    { name = "mypy-extensions" },
-    { name = "pathspec" },
-    { name = "tomli", marker = "python_full_version < '3.11'" },
-    { name = "typing-extensions" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/f8/5c/b0089fe7fef0a994ae5ee07029ced0526082c6cfaaa4c10d40a10e33b097/mypy-1.20.0.tar.gz", hash = "sha256:eb96c84efcc33f0b5e0e04beacf00129dd963b67226b01c00b9dfc8affb464c3", size = 3815028, upload-time = "2026-03-31T16:55:14.959Z" }
-wheels = [
-    { url = "https://files.pythonhosted.org/packages/4d/a2/a965c8c3fcd4fa8b84ba0d46606181b0d0a1d50f274c67877f3e9ed4882c/mypy-1.20.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d99f515f95fd03a90875fdb2cca12ff074aa04490db4d190905851bdf8a549a8", size = 14430138, upload-time = "2026-03-31T16:52:37.843Z" },
-    { url = "https://files.pythonhosted.org/packages/53/6e/043477501deeb8eabbab7f1a2f6cac62cfb631806dc1d6862a04a7f5011b/mypy-1.20.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:bd0212976dc57a5bfeede7c219e7cd66568a32c05c9129686dd487c059c1b88a", size = 13311282, upload-time = "2026-03-31T16:55:11.021Z" },
-    { url = "https://files.pythonhosted.org/packages/65/aa/bd89b247b83128197a214f29f0632ff3c14f54d4cd70d144d157bd7d7d6e/mypy-1.20.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f8426d4d75d68714abc17a4292d922f6ba2cfb984b72c2278c437f6dae797865", size = 13750889, upload-time = "2026-03-31T16:52:02.909Z" },
-    { url = "https://files.pythonhosted.org/packages/fa/9d/2860be7355c45247ccc0be1501c91176318964c2a137bd4743f58ce6200e/mypy-1.20.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:02cca0761c75b42a20a2757ae58713276605eb29a08dd8a6e092aa347c4115ca", size = 14619788, upload-time = "2026-03-31T16:50:48.928Z" },
-    { url = "https://files.pythonhosted.org/packages/75/7f/3ef3e360c91f3de120f205c8ce405e9caf9fc52ef14b65d37073e322c114/mypy-1.20.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b3a49064504be59e59da664c5e149edc1f26c67c4f8e8456f6ba6aba55033018", size = 14918849, upload-time = "2026-03-31T16:51:10.478Z" },
-    { url = "https://files.pythonhosted.org/packages/ae/72/af970dfe167ef788df7c5e6109d2ed0229f164432ce828bc9741a4250e64/mypy-1.20.0-cp310-cp310-win_amd64.whl", hash = "sha256:ebea00201737ad4391142808ed16e875add5c17f676e0912b387739f84991e13", size = 10822007, upload-time = "2026-03-31T16:50:25.268Z" },
-    { url = "https://files.pythonhosted.org/packages/93/94/ba9065c2ebe5421619aff684b793d953e438a8bfe31a320dd6d1e0706e81/mypy-1.20.0-cp310-cp310-win_arm64.whl", hash = "sha256:e80cf77847d0d3e6e3111b7b25db32a7f8762fd4b9a3a72ce53fe16a2863b281", size = 9756158, upload-time = "2026-03-31T16:48:36.213Z" },
-    { url = "https://files.pythonhosted.org/packages/6e/1c/74cb1d9993236910286865679d1c616b136b2eae468493aa939431eda410/mypy-1.20.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4525e7010b1b38334516181c5b81e16180b8e149e6684cee5a727c78186b4e3b", size = 14343972, upload-time = "2026-03-31T16:49:04.887Z" },
-    { url = "https://files.pythonhosted.org/packages/d5/0d/01399515eca280386e308cf57901e68d3a52af18691941b773b3380c1df8/mypy-1.20.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a17c5d0bdcca61ce24a35beb828a2d0d323d3fcf387d7512206888c900193367", size = 13225007, upload-time = "2026-03-31T16:50:08.151Z" },
-    { url = "https://files.pythonhosted.org/packages/56/ac/b4ba5094fb2d7fe9d2037cd8d18bbe02bcf68fd22ab9ff013f55e57ba095/mypy-1.20.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f75ff57defcd0f1d6e006d721ccdec6c88d4f6a7816eb92f1c4890d979d9ee62", size = 13663752, upload-time = "2026-03-31T16:49:26.064Z" },
-    { url = "https://files.pythonhosted.org/packages/db/a7/460678d3cf7da252d2288dad0c602294b6ec22a91932ec368cc11e44bb6e/mypy-1.20.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b503ab55a836136b619b5fc21c8803d810c5b87551af8600b72eecafb0059cb0", size = 14532265, upload-time = "2026-03-31T16:53:55.077Z" },
-    { url = "https://files.pythonhosted.org/packages/a3/3e/051cca8166cf0438ae3ea80e0e7c030d7a8ab98dffc93f80a1aa3f23c1a2/mypy-1.20.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1973868d2adbb4584a3835780b27436f06d1dc606af5be09f187aaa25be1070f", size = 14768476, upload-time = "2026-03-31T16:50:34.587Z" },
-    { url = "https://files.pythonhosted.org/packages/be/66/8e02ec184f852ed5c4abb805583305db475930854e09964b55e107cdcbc4/mypy-1.20.0-cp311-cp311-win_amd64.whl", hash = "sha256:2fcedb16d456106e545b2bfd7ef9d24e70b38ec252d2a629823a4d07ebcdb69e", size = 10818226, upload-time = "2026-03-31T16:53:15.624Z" },
-    { url = "https://files.pythonhosted.org/packages/13/4b/383ad1924b28f41e4879a74151e7a5451123330d45652da359f9183bcd45/mypy-1.20.0-cp311-cp311-win_arm64.whl", hash = "sha256:379edf079ce44ac8d2805bcf9b3dd7340d4f97aad3a5e0ebabbf9d125b84b442", size = 9750091, upload-time = "2026-03-31T16:54:12.162Z" },
-    { url = "https://files.pythonhosted.org/packages/be/dd/3afa29b58c2e57c79116ed55d700721c3c3b15955e2b6251dd165d377c0e/mypy-1.20.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:002b613ae19f4ac7d18b7e168ffe1cb9013b37c57f7411984abbd3b817b0a214", size = 14509525, upload-time = "2026-03-31T16:55:01.824Z" },
-    { url = "https://files.pythonhosted.org/packages/54/eb/227b516ab8cad9f2a13c5e7a98d28cd6aa75e9c83e82776ae6c1c4c046c7/mypy-1.20.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a9336b5e6712f4adaf5afc3203a99a40b379049104349d747eb3e5a3aa23ac2e", size = 13326469, upload-time = "2026-03-31T16:51:41.23Z" },
-    { url = "https://files.pythonhosted.org/packages/57/d4/1ddb799860c1b5ac6117ec307b965f65deeb47044395ff01ab793248a591/mypy-1.20.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f13b3e41bce9d257eded794c0f12878af3129d80aacd8a3ee0dee51f3a978651", size = 13705953, upload-time = "2026-03-31T16:48:55.69Z" },
-    { url = "https://files.pythonhosted.org/packages/c5/b7/54a720f565a87b893182a2a393370289ae7149e4715859e10e1c05e49154/mypy-1.20.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9804c3ad27f78e54e58b32e7cb532d128b43dbfb9f3f9f06262b821a0f6bd3f5", size = 14710363, upload-time = "2026-03-31T16:53:26.948Z" },
-    { url = "https://files.pythonhosted.org/packages/b2/2a/74810274848d061f8a8ea4ac23aaad43bd3d8c1882457999c2e568341c57/mypy-1.20.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:697f102c5c1d526bdd761a69f17c6070f9892eebcb94b1a5963d679288c09e78", size = 14947005, upload-time = "2026-03-31T16:50:17.591Z" },
-    { url = "https://files.pythonhosted.org/packages/77/91/21b8ba75f958bcda75690951ce6fa6b7138b03471618959529d74b8544e2/mypy-1.20.0-cp312-cp312-win_amd64.whl", hash = "sha256:0ecd63f75fdd30327e4ad8b5704bd6d91fc6c1b2e029f8ee14705e1207212489", size = 10880616, upload-time = "2026-03-31T16:52:19.986Z" },
-    { url = "https://files.pythonhosted.org/packages/8a/15/3d8198ef97c1ca03aea010cce4f1d4f3bc5d9849e8c0140111ca2ead9fdd/mypy-1.20.0-cp312-cp312-win_arm64.whl", hash = "sha256:f194db59657c58593a3c47c6dfd7bad4ef4ac12dbc94d01b3a95521f78177e33", size = 9813091, upload-time = "2026-03-31T16:53:44.385Z" },
-    { url = "https://files.pythonhosted.org/packages/d6/a7/f64ea7bd592fa431cb597418b6dec4a47f7d0c36325fec7ac67bc8402b94/mypy-1.20.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b20c8b0fd5877abdf402e79a3af987053de07e6fb208c18df6659f708b535134", size = 14485344, upload-time = "2026-03-31T16:49:16.78Z" },
-    { url = "https://files.pythonhosted.org/packages/bb/72/8927d84cfc90c6abea6e96663576e2e417589347eb538749a464c4c218a0/mypy-1.20.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:367e5c993ba34d5054d11937d0485ad6dfc60ba760fa326c01090fc256adf15c", size = 13327400, upload-time = "2026-03-31T16:53:08.02Z" },
-    { url = "https://files.pythonhosted.org/packages/ab/4a/11ab99f9afa41aa350178d24a7d2da17043228ea10f6456523f64b5a6cf6/mypy-1.20.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f799d9db89fc00446f03281f84a221e50018fc40113a3ba9864b132895619ebe", size = 13706384, upload-time = "2026-03-31T16:52:28.577Z" },
-    { url = "https://files.pythonhosted.org/packages/42/79/694ca73979cfb3535ebfe78733844cd5aff2e63304f59bf90585110d975a/mypy-1.20.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:555658c611099455b2da507582ea20d2043dfdfe7f5ad0add472b1c6238b433f", size = 14700378, upload-time = "2026-03-31T16:48:45.527Z" },
-    { url = "https://files.pythonhosted.org/packages/84/24/a022ccab3a46e3d2cdf2e0e260648633640eb396c7e75d5a42818a8d3971/mypy-1.20.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:efe8d70949c3023698c3fca1e94527e7e790a361ab8116f90d11221421cd8726", size = 14932170, upload-time = "2026-03-31T16:49:36.038Z" },
-    { url = "https://files.pythonhosted.org/packages/d8/9b/549228d88f574d04117e736f55958bd4908f980f9f5700a07aeb85df005b/mypy-1.20.0-cp313-cp313-win_amd64.whl", hash = "sha256:f49590891d2c2f8a9de15614e32e459a794bcba84693c2394291a2038bbaaa69", size = 10888526, upload-time = "2026-03-31T16:50:59.827Z" },
-    { url = "https://files.pythonhosted.org/packages/91/17/15095c0e54a8bc04d22d4ff06b2139d5f142c2e87520b4e39010c4862771/mypy-1.20.0-cp313-cp313-win_arm64.whl", hash = "sha256:76a70bf840495729be47510856b978f1b0ec7d08f257ca38c9d932720bf6b43e", size = 9816456, upload-time = "2026-03-31T16:49:59.537Z" },
-    { url = "https://files.pythonhosted.org/packages/4e/0e/6ca4a84cbed9e62384bc0b2974c90395ece5ed672393e553996501625fc5/mypy-1.20.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:0f42dfaab7ec1baff3b383ad7af562ab0de573c5f6edb44b2dab016082b89948", size = 14483331, upload-time = "2026-03-31T16:52:57.999Z" },
-    { url = "https://files.pythonhosted.org/packages/7d/c5/5fe9d8a729dd9605064691816243ae6c49fde0bd28f6e5e17f6a24203c43/mypy-1.20.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:31b5dbb55293c1bd27c0fc813a0d2bb5ceef9d65ac5afa2e58f829dab7921fd5", size = 13342047, upload-time = "2026-03-31T16:54:21.555Z" },
-    { url = "https://files.pythonhosted.org/packages/4c/33/e18bcfa338ca4e6b2771c85d4c5203e627d0c69d9de5c1a2cf2ba13320ba/mypy-1.20.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:49d11c6f573a5a08f77fad13faff2139f6d0730ebed2cfa9b3d2702671dd7188", size = 13719585, upload-time = "2026-03-31T16:51:53.89Z" },
-    { url = "https://files.pythonhosted.org/packages/6b/8d/93491ff7b79419edc7eabf95cb3b3f7490e2e574b2855c7c7e7394ff933f/mypy-1.20.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7d3243c406773185144527f83be0e0aefc7bf4601b0b2b956665608bf7c98a83", size = 14685075, upload-time = "2026-03-31T16:54:04.464Z" },
-    { url = "https://files.pythonhosted.org/packages/b5/9d/d924b38a4923f8d164bf2b4ec98bf13beaf6e10a5348b4b137eadae40a6e/mypy-1.20.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:a79c1eba7ac4209f2d850f0edd0a2f8bba88cbfdfefe6fb76a19e9d4fe5e71a2", size = 14919141, upload-time = "2026-03-31T16:54:51.785Z" },
-    { url = "https://files.pythonhosted.org/packages/59/98/1da9977016678c0b99d43afe52ed00bb3c1a0c4c995d3e6acca1a6ebb9b4/mypy-1.20.0-cp314-cp314-win_amd64.whl", hash = "sha256:00e047c74d3ec6e71a2eb88e9ea551a2edb90c21f993aefa9e0d2a898e0bb732", size = 11050925, upload-time = "2026-03-31T16:51:30.758Z" },
-    { url = "https://files.pythonhosted.org/packages/5e/e3/ba0b7a3143e49a9c4f5967dde6ea4bf8e0b10ecbbcca69af84027160ee89/mypy-1.20.0-cp314-cp314-win_arm64.whl", hash = "sha256:931a7630bba591593dcf6e97224a21ff80fb357e7982628d25e3c618e7f598ef", size = 10001089, upload-time = "2026-03-31T16:49:43.632Z" },
-    { url = "https://files.pythonhosted.org/packages/12/28/e617e67b3be9d213cda7277913269c874eb26472489f95d09d89765ce2d8/mypy-1.20.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:26c8b52627b6552f47ff11adb4e1509605f094e29815323e487fc0053ebe93d1", size = 15534710, upload-time = "2026-03-31T16:52:12.506Z" },
-    { url = "https://files.pythonhosted.org/packages/6e/0c/3b5f2d3e45dc7169b811adce8451679d9430399d03b168f9b0489f43adaa/mypy-1.20.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:39362cdb4ba5f916e7976fccecaab1ba3a83e35f60fa68b64e9a70e221bb2436", size = 14393013, upload-time = "2026-03-31T16:54:41.186Z" },
-    { url = "https://files.pythonhosted.org/packages/a3/49/edc8b0aa145cc09c1c74f7ce2858eead9329931dcbbb26e2ad40906daa4e/mypy-1.20.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:34506397dbf40c15dc567635d18a21d33827e9ab29014fb83d292a8f4f8953b6", size = 15047240, upload-time = "2026-03-31T16:54:31.955Z" },
-    { url = "https://files.pythonhosted.org/packages/42/37/a946bb416e37a57fa752b3100fd5ede0e28df94f92366d1716555d47c454/mypy-1.20.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:555493c44a4f5a1b58d611a43333e71a9981c6dbe26270377b6f8174126a0526", size = 15858565, upload-time = "2026-03-31T16:53:36.997Z" },
-    { url = "https://files.pythonhosted.org/packages/2f/99/7690b5b5b552db1bd4ff362e4c0eb3107b98d680835e65823fbe888c8b78/mypy-1.20.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:2721f0ce49cb74a38f00c50da67cb7d36317b5eda38877a49614dc018e91c787", size = 16087874, upload-time = "2026-03-31T16:52:48.313Z" },
-    { url = "https://files.pythonhosted.org/packages/aa/76/53e893a498138066acd28192b77495c9357e5a58cc4be753182846b43315/mypy-1.20.0-cp314-cp314t-win_amd64.whl", hash = "sha256:47781555a7aa5fedcc2d16bcd72e0dc83eb272c10dd657f9fb3f9cc08e2e6abb", size = 12572380, upload-time = "2026-03-31T16:49:52.454Z" },
-    { url = "https://files.pythonhosted.org/packages/76/9c/6dbdae21f01b7aacddc2c0bbf3c5557aa547827fdf271770fe1e521e7093/mypy-1.20.0-cp314-cp314t-win_arm64.whl", hash = "sha256:c70380fe5d64010f79fb863b9081c7004dd65225d2277333c219d93a10dad4dd", size = 10381174, upload-time = "2026-03-31T16:51:20.179Z" },
-    { url = "https://files.pythonhosted.org/packages/21/66/4d734961ce167f0fd8380769b3b7c06dbdd6ff54c2190f3f2ecd22528158/mypy-1.20.0-py3-none-any.whl", hash = "sha256:a6e0641147cbfa7e4e94efdb95c2dab1aff8cfc159ded13e07f308ddccc8c48e", size = 2636365, upload-time = "2026-03-31T16:51:44.911Z" },
-]
-
 [[package]]
 name = "mypy-extensions"
 version = "1.1.0"
@@ -1938,12 +1880,12 @@ dev = [
     { name = "mkdocs-material" },
     { name = "mkdocs-redirects" },
     { name = "mkdocstrings", extra = ["python"] },
-    { name = "mypy" },
     { name = "pillow" },
     { name = "prek" },
     { name = "pytest" },
     { name = "pyyaml" },
     { name = "ruff" },
+    { name = "ty" },
     { name = "typer" },
     { name = "typing-extensions" },
 ]
@@ -1976,9 +1918,9 @@ tests = [
     { name = "fastapi" },
     { name = "httpx" },
     { name = "jinja2" },
-    { name = "mypy" },
     { name = "pytest" },
     { name = "ruff" },
+    { name = "ty" },
     { name = "typing-extensions" },
 ]
 
@@ -2006,12 +1948,12 @@ dev = [
     { name = "mkdocs-material", specifier = ">=9.7.5" },
     { name = "mkdocs-redirects", specifier = ">=1.2.1" },
     { name = "mkdocstrings", extras = ["python"], specifier = ">=1.0.3" },
-    { name = "mypy", specifier = ">=1.19.1" },
     { name = "pillow", specifier = ">=12.1.1" },
     { name = "prek", specifier = ">=0.2.24,<1.0.0" },
     { name = "pytest", specifier = ">=7.0.1" },
     { name = "pyyaml", specifier = ">=5.3.1" },
     { name = "ruff", specifier = ">=0.15.6" },
+    { name = "ty", specifier = ">=0.0.25" },
     { name = "typer", specifier = ">=0.24.1" },
     { name = "typing-extensions", specifier = ">=4.15.0" },
 ]
@@ -2044,9 +1986,9 @@ tests = [
     { name = "fastapi", specifier = ">=0.128.0" },
     { name = "httpx", specifier = ">=0.28.1" },
     { name = "jinja2", specifier = ">=3.1.6" },
-    { name = "mypy", specifier = ">=1.19.1" },
     { name = "pytest", specifier = ">=7.0.1" },
     { name = "ruff", specifier = ">=0.15.6" },
+    { name = "ty", specifier = ">=0.0.25" },
     { name = "typing-extensions", specifier = ">=4.15.0" },
 ]
 
@@ -2145,6 +2087,30 @@ wheels = [
     { url = "https://files.pythonhosted.org/packages/77/b8/0135fadc89e73be292b473cb820b4f5a08197779206b33191e801feeae40/tomli-2.3.0-py3-none-any.whl", hash = "sha256:e95b1af3c5b07d9e643909b5abbec77cd9f1217e6d0bca72b0234736b9fb1f1b", size = 14408, upload-time = "2025-10-08T22:01:46.04Z" },
 ]
 
+[[package]]
+name = "ty"
+version = "0.0.26"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/18/94/4879b81f8681117ccaf31544579304f6dc2ddcc0c67f872afb35869643a2/ty-0.0.26.tar.gz", hash = "sha256:0496b62405d62de7b954d6d677dc1cc5d3046197215d7a0a7fef37745d7b6d29", size = 5393643, upload-time = "2026-03-26T16:27:11.067Z" }
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/83/24/99fe33ecd7e16d23c53b0d4244778c6d1b6eb1663b091236dcba22882d67/ty-0.0.26-py3-none-linux_armv6l.whl", hash = "sha256:35beaa56cf59725fd59ab35d8445bbd40b97fe76db39b052b1fcb31f9bf8adf7", size = 10521856, upload-time = "2026-03-26T16:27:06.335Z" },
+    { url = "https://files.pythonhosted.org/packages/55/97/1b5e939e2ff69b9bb279ab680bfa8f677d886309a1ac8d9588fd6ce58146/ty-0.0.26-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:487a0be58ab0eb02e31ba71eb6953812a0f88e50633469b0c0ce3fb795fe0fa1", size = 10320958, upload-time = "2026-03-26T16:27:13.849Z" },
+    { url = "https://files.pythonhosted.org/packages/71/25/37081461e13d38a190e5646948d7bc42084f7bd1c6b44f12550be3923e7e/ty-0.0.26-py3-none-macosx_11_0_arm64.whl", hash = "sha256:a01b7de5693379646d423b68f119719a1338a20017ba48a93eefaff1ee56f97b", size = 9799905, upload-time = "2026-03-26T16:26:55.805Z" },
+    { url = "https://files.pythonhosted.org/packages/a1/1c/295d8f55a7b0e037dfc3a5ec4bdda3ab3cbca6f492f725bf269f96a4d841/ty-0.0.26-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:628c3ee869d113dd2bd249925662fd39d9d0305a6cb38f640ddaa7436b74a1ef", size = 10317507, upload-time = "2026-03-26T16:27:31.887Z" },
+    { url = "https://files.pythonhosted.org/packages/1d/62/48b3875c5d2f48fe017468d4bbdde1164c76a8184374f1d5e6162cf7d9b8/ty-0.0.26-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:63d04f35f5370cbc91c0b9675dc83e0c53678125a7b629c9c95769e86f123e65", size = 10319821, upload-time = "2026-03-26T16:27:29.647Z" },
+    { url = "https://files.pythonhosted.org/packages/ff/28/cfb2d495046d5bf42d532325cea7412fa1189912d549dbfae417a24fd794/ty-0.0.26-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a53c4e6f6a91927f8b90e584a4b12bcde05b0c1870ddff8d17462168ad7947a", size = 10831757, upload-time = "2026-03-26T16:27:37.441Z" },
+    { url = "https://files.pythonhosted.org/packages/26/bf/dbc3e42f448a2d862651de070b4108028c543ca18cab096b38d7de449915/ty-0.0.26-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:caf2ced0e58d898d5e3ba5cb843e0ebd377c8a461464748586049afbd9321f51", size = 11369556, upload-time = "2026-03-26T16:26:58.655Z" },
+    { url = "https://files.pythonhosted.org/packages/92/4c/6d2f8f34bc6d502ab778c9345a4a936a72ae113de11329c1764bb1f204f6/ty-0.0.26-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:384807bbcb7d7ce9b97ee5aaa6417a8ae03ccfb426c52b08018ca62cf60f5430", size = 11085679, upload-time = "2026-03-26T16:27:21.746Z" },
+    { url = "https://files.pythonhosted.org/packages/cc/f4/f3f61c203bc980dd9bba0ba7ed3c6e81ddfd36b286330f9487c2c7d041aa/ty-0.0.26-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8a2c766a94d79b4f82995d41229702caf2d76e5c440ec7e543d05c70e98bf8ab", size = 10900581, upload-time = "2026-03-26T16:27:24.39Z" },
+    { url = "https://files.pythonhosted.org/packages/3d/fd/3ca1b4e4bdd129829e9ce78677e0f8e0f1038a7702dccecfa52f037c6046/ty-0.0.26-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:f41ac45a0f8e3e8e181508d863a0a62156341db0f624ffd004b97ee550a9de80", size = 10294401, upload-time = "2026-03-26T16:27:03.999Z" },
+    { url = "https://files.pythonhosted.org/packages/de/20/4ee3d8c3f90e008843795c765cb8bb245f188c23e5e5cc612c7697406fba/ty-0.0.26-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:73eb8327a34d529438dfe4db46796946c4e825167cbee434dc148569892e435f", size = 10351469, upload-time = "2026-03-26T16:27:19.003Z" },
+    { url = "https://files.pythonhosted.org/packages/3d/b1/9fb154ade65906d4148f0b999c4a8257c2a34253cb72e15d84c1f04a064e/ty-0.0.26-py3-none-musllinux_1_2_i686.whl", hash = "sha256:4bb53a79259516535a1b55f613ba1619e9c666854946474ca8418c35a5c4fd60", size = 10529488, upload-time = "2026-03-26T16:27:01.378Z" },
+    { url = "https://files.pythonhosted.org/packages/a5/70/9b02b03b1862e27b64143db65946d68b138160a5b6bfea193bee0b8bbc34/ty-0.0.26-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:2f0e75edc1aeb1b4b84af516c7891f631254a4ca3dcd15e848fa1e061e1fe9da", size = 10999015, upload-time = "2026-03-26T16:27:34.636Z" },
+    { url = "https://files.pythonhosted.org/packages/21/16/0a56b8667296e2989b9d48095472d98ebf57a0006c71f2a101bbc62a142d/ty-0.0.26-py3-none-win32.whl", hash = "sha256:943c998c5523ed6b519c899c0c39b26b4c751a9759e460fb964765a44cde226f", size = 9912378, upload-time = "2026-03-26T16:27:08.999Z" },
+    { url = "https://files.pythonhosted.org/packages/60/c2/fef0d4bba9cd89a82d725b3b1a66efb1b36629ecf0fb1d8e916cb75b8829/ty-0.0.26-py3-none-win_amd64.whl", hash = "sha256:19c856d343efeb1ecad8ee220848f5d2c424daf7b2feda357763ad3036e2172f", size = 10863737, upload-time = "2026-03-26T16:27:27.06Z" },
+    { url = "https://files.pythonhosted.org/packages/4d/05/888ebcb3c4d3b6b72d5d3241fddd299142caa3c516e6d26a9cd887dfed3b/ty-0.0.26-py3-none-win_arm64.whl", hash = "sha256:2cde58ccffa046db1223dc28f3e7d4f2c7da8267e97cc5cd186af6fe85f1758a", size = 10285408, upload-time = "2026-03-26T16:27:16.432Z" },
+]
+
 [[package]]
 name = "typer"
 version = "0.24.1"