diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f21c23186b..56ecf1e7f3 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -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 require_serial: true language: unsupported pass_filenames: false diff --git a/pyproject.toml b/pyproject.toml index 00fed9b72e..1788fca00e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -81,10 +81,10 @@ tests = [ "fastapi>=0.128.0", "httpx==0.28.1", "jinja2==3.1.6", - "mypy==1.19.1", "pre-commit>=2.17.0,<5.0.0", "pytest>=7.0.1,<10.0.0", "ruff==0.15.5", + "ty>=0.0.9", "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 diff --git a/scripts/generate_select.py b/scripts/generate_select.py index cbb842b367..20170c0937 100644 --- a/scripts/generate_select.py +++ b/scripts/generate_select.py @@ -37,7 +37,7 @@ class Arg(BaseModel): 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) diff --git a/scripts/lint.sh b/scripts/lint.sh index e4a7b5bea7..9b2366d226 100755 --- a/scripts/lint.sh +++ b/scripts/lint.sh @@ -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 diff --git a/sqlmodel/main.py b/sqlmodel/main.py index 300031de8b..4a51488a59 100644 --- a/sqlmodel/main.py +++ b/sqlmodel/main.py @@ -52,7 +52,7 @@ 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, @@ -177,7 +177,7 @@ def __init__( 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 +398,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,17 +525,17 @@ class SQLModelMetaclass(ModelMetaclass, DeclarativeMeta): model_fields: ClassVar[dict[str, FieldInfo]] # Replicate SQLAlchemy - def __setattr__(cls, name: str, value: Any) -> None: + def __setattr__(cls, key: str, value: Any) -> None: if is_table_model_class(cls): - DeclarativeMeta.__setattr__(cls, name, value) + DeclarativeMeta.__setattr__(cls, key, value) else: - super().__setattr__(name, value) + super().__setattr__(key, value) - def __delattr__(cls, name: str) -> None: + def __delattr__(cls, key: str) -> None: if is_table_model_class(cls): - DeclarativeMeta.__delattr__(cls, name) + DeclarativeMeta.__delattr__(cls, key) else: - super().__delattr__(name) + super().__delattr__(key) # From Pydantic def __new__( @@ -649,7 +649,7 @@ def __init__( # 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 +738,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 +773,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,7 +797,7 @@ def get_column_from_field(field: Any) -> Column: # type: ignore return Column(sa_type, *args, **kwargs) -class_registry = weakref.WeakValueDictionary() # type: ignore +class_registry = weakref.WeakValueDictionary() default_registry = registry() @@ -850,7 +850,7 @@ def __setattr__(self, name: str, value: Any) -> None: 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 diff --git a/sqlmodel/sql/_expression_select_cls.py b/sqlmodel/sql/_expression_select_cls.py index 1229c22935..124929d2c3 100644 --- a/sqlmodel/sql/_expression_select_cls.py +++ b/sqlmodel/sql/_expression_select_cls.py @@ -20,13 +20,13 @@ def where(self, *whereclause: _ColumnExpressionArgument[bool] | bool) -> Self: """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]): diff --git a/sqlmodel/sql/_expression_select_gen.py b/sqlmodel/sql/_expression_select_gen.py index 83d934c68b..025117654e 100644 --- a/sqlmodel/sql/_expression_select_gen.py +++ b/sqlmodel/sql/_expression_select_gen.py @@ -29,9 +29,9 @@ _TScalar_0 = TypeVar( "_TScalar_0", - Column, # type: ignore - Sequence, # type: ignore - Mapping, # type: ignore + Column, + Sequence, + Mapping, UUID, datetime, float, @@ -47,9 +47,9 @@ _TScalar_1 = TypeVar( "_TScalar_1", - Column, # type: ignore - Sequence, # type: ignore - Mapping, # type: ignore + Column, + Sequence, + Mapping, UUID, datetime, float, @@ -65,9 +65,9 @@ _TScalar_2 = TypeVar( "_TScalar_2", - Column, # type: ignore - Sequence, # type: ignore - Mapping, # type: ignore + Column, + Sequence, + Mapping, UUID, datetime, float, @@ -83,9 +83,9 @@ _TScalar_3 = TypeVar( "_TScalar_3", - Column, # type: ignore - Sequence, # type: ignore - Mapping, # type: ignore + Column, + Sequence, + Mapping, UUID, datetime, float, @@ -107,99 +107,98 @@ 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, @@ -207,71 +206,71 @@ def select( # type: ignore @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, @@ -279,70 +278,70 @@ def select( # type: ignore @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, @@ -353,7 +352,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) diff --git a/sqlmodel/sql/_expression_select_gen.py.jinja2 b/sqlmodel/sql/_expression_select_gen.py.jinja2 index 2ce54cb2fa..fe34437629 100644 --- a/sqlmodel/sql/_expression_select_gen.py.jinja2 +++ b/sqlmodel/sql/_expression_select_gen.py.jinja2 @@ -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, @@ -52,8 +52,7 @@ 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,7 +60,7 @@ def select(__ent0: _TScalar_0) -> SelectOfScalar[_TScalar_0]: # type: ignore {% for signature in signatures %} @overload -def select( # type: ignore +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 %}]]: ... @@ -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) diff --git a/sqlmodel/sql/sqltypes.py b/sqlmodel/sql/sqltypes.py index 512daacbab..3119b1b624 100644 --- a/sqlmodel/sql/sqltypes.py +++ b/sqlmodel/sql/sqltypes.py @@ -4,7 +4,7 @@ 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 604832601b..04757573f5 100644 --- a/uv.lock +++ b/uv.lock @@ -1149,52 +1149,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.19.1" -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/f5/db/4efed9504bc01309ab9c2da7e352cc223569f05478012b5d9ece38fd44d2/mypy-1.19.1.tar.gz", hash = "sha256:19d88bb05303fe63f71dd2c6270daca27cb9401c4ca8255fe50d1d920e0eb9ba", size = 3582404, upload-time = "2025-12-15T05:03:48.42Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/2f/63/e499890d8e39b1ff2df4c0c6ce5d371b6844ee22b8250687a99fd2f657a8/mypy-1.19.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5f05aa3d375b385734388e844bc01733bd33c644ab48e9684faa54e5389775ec", size = 13101333, upload-time = "2025-12-15T05:03:03.28Z" }, - { url = "https://files.pythonhosted.org/packages/72/4b/095626fc136fba96effc4fd4a82b41d688ab92124f8c4f7564bffe5cf1b0/mypy-1.19.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:022ea7279374af1a5d78dfcab853fe6a536eebfda4b59deab53cd21f6cd9f00b", size = 12164102, upload-time = "2025-12-15T05:02:33.611Z" }, - { url = "https://files.pythonhosted.org/packages/0c/5b/952928dd081bf88a83a5ccd49aaecfcd18fd0d2710c7ff07b8fb6f7032b9/mypy-1.19.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee4c11e460685c3e0c64a4c5de82ae143622410950d6be863303a1c4ba0e36d6", size = 12765799, upload-time = "2025-12-15T05:03:28.44Z" }, - { url = "https://files.pythonhosted.org/packages/2a/0d/93c2e4a287f74ef11a66fb6d49c7a9f05e47b0a4399040e6719b57f500d2/mypy-1.19.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:de759aafbae8763283b2ee5869c7255391fbc4de3ff171f8f030b5ec48381b74", size = 13522149, upload-time = "2025-12-15T05:02:36.011Z" }, - { url = "https://files.pythonhosted.org/packages/7b/0e/33a294b56aaad2b338d203e3a1d8b453637ac36cb278b45005e0901cf148/mypy-1.19.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ab43590f9cd5108f41aacf9fca31841142c786827a74ab7cc8a2eacb634e09a1", size = 13810105, upload-time = "2025-12-15T05:02:40.327Z" }, - { url = "https://files.pythonhosted.org/packages/0e/fd/3e82603a0cb66b67c5e7abababce6bf1a929ddf67bf445e652684af5c5a0/mypy-1.19.1-cp310-cp310-win_amd64.whl", hash = "sha256:2899753e2f61e571b3971747e302d5f420c3fd09650e1951e99f823bc3089dac", size = 10057200, upload-time = "2025-12-15T05:02:51.012Z" }, - { url = "https://files.pythonhosted.org/packages/ef/47/6b3ebabd5474d9cdc170d1342fbf9dddc1b0ec13ec90bf9004ee6f391c31/mypy-1.19.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d8dfc6ab58ca7dda47d9237349157500468e404b17213d44fc1cb77bce532288", size = 13028539, upload-time = "2025-12-15T05:03:44.129Z" }, - { url = "https://files.pythonhosted.org/packages/5c/a6/ac7c7a88a3c9c54334f53a941b765e6ec6c4ebd65d3fe8cdcfbe0d0fd7db/mypy-1.19.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e3f276d8493c3c97930e354b2595a44a21348b320d859fb4a2b9f66da9ed27ab", size = 12083163, upload-time = "2025-12-15T05:03:37.679Z" }, - { url = "https://files.pythonhosted.org/packages/67/af/3afa9cf880aa4a2c803798ac24f1d11ef72a0c8079689fac5cfd815e2830/mypy-1.19.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2abb24cf3f17864770d18d673c85235ba52456b36a06b6afc1e07c1fdcd3d0e6", size = 12687629, upload-time = "2025-12-15T05:02:31.526Z" }, - { url = "https://files.pythonhosted.org/packages/2d/46/20f8a7114a56484ab268b0ab372461cb3a8f7deed31ea96b83a4e4cfcfca/mypy-1.19.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a009ffa5a621762d0c926a078c2d639104becab69e79538a494bcccb62cc0331", size = 13436933, upload-time = "2025-12-15T05:03:15.606Z" }, - { url = "https://files.pythonhosted.org/packages/5b/f8/33b291ea85050a21f15da910002460f1f445f8007adb29230f0adea279cb/mypy-1.19.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f7cee03c9a2e2ee26ec07479f38ea9c884e301d42c6d43a19d20fb014e3ba925", size = 13661754, upload-time = "2025-12-15T05:02:26.731Z" }, - { url = "https://files.pythonhosted.org/packages/fd/a3/47cbd4e85bec4335a9cd80cf67dbc02be21b5d4c9c23ad6b95d6c5196bac/mypy-1.19.1-cp311-cp311-win_amd64.whl", hash = "sha256:4b84a7a18f41e167f7995200a1d07a4a6810e89d29859df936f1c3923d263042", size = 10055772, upload-time = "2025-12-15T05:03:26.179Z" }, - { url = "https://files.pythonhosted.org/packages/06/8a/19bfae96f6615aa8a0604915512e0289b1fad33d5909bf7244f02935d33a/mypy-1.19.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:a8174a03289288c1f6c46d55cef02379b478bfbc8e358e02047487cad44c6ca1", size = 13206053, upload-time = "2025-12-15T05:03:46.622Z" }, - { url = "https://files.pythonhosted.org/packages/a5/34/3e63879ab041602154ba2a9f99817bb0c85c4df19a23a1443c8986e4d565/mypy-1.19.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ffcebe56eb09ff0c0885e750036a095e23793ba6c2e894e7e63f6d89ad51f22e", size = 12219134, upload-time = "2025-12-15T05:03:24.367Z" }, - { url = "https://files.pythonhosted.org/packages/89/cc/2db6f0e95366b630364e09845672dbee0cbf0bbe753a204b29a944967cd9/mypy-1.19.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b64d987153888790bcdb03a6473d321820597ab8dd9243b27a92153c4fa50fd2", size = 12731616, upload-time = "2025-12-15T05:02:44.725Z" }, - { url = "https://files.pythonhosted.org/packages/00/be/dd56c1fd4807bc1eba1cf18b2a850d0de7bacb55e158755eb79f77c41f8e/mypy-1.19.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c35d298c2c4bba75feb2195655dfea8124d855dfd7343bf8b8c055421eaf0cf8", size = 13620847, upload-time = "2025-12-15T05:03:39.633Z" }, - { url = "https://files.pythonhosted.org/packages/6d/42/332951aae42b79329f743bf1da088cd75d8d4d9acc18fbcbd84f26c1af4e/mypy-1.19.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:34c81968774648ab5ac09c29a375fdede03ba253f8f8287847bd480782f73a6a", size = 13834976, upload-time = "2025-12-15T05:03:08.786Z" }, - { url = "https://files.pythonhosted.org/packages/6f/63/e7493e5f90e1e085c562bb06e2eb32cae27c5057b9653348d38b47daaecc/mypy-1.19.1-cp312-cp312-win_amd64.whl", hash = "sha256:b10e7c2cd7870ba4ad9b2d8a6102eb5ffc1f16ca35e3de6bfa390c1113029d13", size = 10118104, upload-time = "2025-12-15T05:03:10.834Z" }, - { url = "https://files.pythonhosted.org/packages/de/9f/a6abae693f7a0c697dbb435aac52e958dc8da44e92e08ba88d2e42326176/mypy-1.19.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e3157c7594ff2ef1634ee058aafc56a82db665c9438fd41b390f3bde1ab12250", size = 13201927, upload-time = "2025-12-15T05:02:29.138Z" }, - { url = "https://files.pythonhosted.org/packages/9a/a4/45c35ccf6e1c65afc23a069f50e2c66f46bd3798cbe0d680c12d12935caa/mypy-1.19.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bdb12f69bcc02700c2b47e070238f42cb87f18c0bc1fc4cdb4fb2bc5fd7a3b8b", size = 12206730, upload-time = "2025-12-15T05:03:01.325Z" }, - { url = "https://files.pythonhosted.org/packages/05/bb/cdcf89678e26b187650512620eec8368fded4cfd99cfcb431e4cdfd19dec/mypy-1.19.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f859fb09d9583a985be9a493d5cfc5515b56b08f7447759a0c5deaf68d80506e", size = 12724581, upload-time = "2025-12-15T05:03:20.087Z" }, - { url = "https://files.pythonhosted.org/packages/d1/32/dd260d52babf67bad8e6770f8e1102021877ce0edea106e72df5626bb0ec/mypy-1.19.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c9a6538e0415310aad77cb94004ca6482330fece18036b5f360b62c45814c4ef", size = 13616252, upload-time = "2025-12-15T05:02:49.036Z" }, - { url = "https://files.pythonhosted.org/packages/71/d0/5e60a9d2e3bd48432ae2b454b7ef2b62a960ab51292b1eda2a95edd78198/mypy-1.19.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:da4869fc5e7f62a88f3fe0b5c919d1d9f7ea3cef92d3689de2823fd27e40aa75", size = 13840848, upload-time = "2025-12-15T05:02:55.95Z" }, - { url = "https://files.pythonhosted.org/packages/98/76/d32051fa65ecf6cc8c6610956473abdc9b4c43301107476ac03559507843/mypy-1.19.1-cp313-cp313-win_amd64.whl", hash = "sha256:016f2246209095e8eda7538944daa1d60e1e8134d98983b9fc1e92c1fc0cb8dd", size = 10135510, upload-time = "2025-12-15T05:02:58.438Z" }, - { url = "https://files.pythonhosted.org/packages/de/eb/b83e75f4c820c4247a58580ef86fcd35165028f191e7e1ba57128c52782d/mypy-1.19.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:06e6170bd5836770e8104c8fdd58e5e725cfeb309f0a6c681a811f557e97eac1", size = 13199744, upload-time = "2025-12-15T05:03:30.823Z" }, - { url = "https://files.pythonhosted.org/packages/94/28/52785ab7bfa165f87fcbb61547a93f98bb20e7f82f90f165a1f69bce7b3d/mypy-1.19.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:804bd67b8054a85447c8954215a906d6eff9cabeabe493fb6334b24f4bfff718", size = 12215815, upload-time = "2025-12-15T05:02:42.323Z" }, - { url = "https://files.pythonhosted.org/packages/0a/c6/bdd60774a0dbfb05122e3e925f2e9e846c009e479dcec4821dad881f5b52/mypy-1.19.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:21761006a7f497cb0d4de3d8ef4ca70532256688b0523eee02baf9eec895e27b", size = 12740047, upload-time = "2025-12-15T05:03:33.168Z" }, - { url = "https://files.pythonhosted.org/packages/32/2a/66ba933fe6c76bd40d1fe916a83f04fed253152f451a877520b3c4a5e41e/mypy-1.19.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:28902ee51f12e0f19e1e16fbe2f8f06b6637f482c459dd393efddd0ec7f82045", size = 13601998, upload-time = "2025-12-15T05:03:13.056Z" }, - { url = "https://files.pythonhosted.org/packages/e3/da/5055c63e377c5c2418760411fd6a63ee2b96cf95397259038756c042574f/mypy-1.19.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:481daf36a4c443332e2ae9c137dfee878fcea781a2e3f895d54bd3002a900957", size = 13807476, upload-time = "2025-12-15T05:03:17.977Z" }, - { url = "https://files.pythonhosted.org/packages/cd/09/4ebd873390a063176f06b0dbf1f7783dd87bd120eae7727fa4ae4179b685/mypy-1.19.1-cp314-cp314-win_amd64.whl", hash = "sha256:8bb5c6f6d043655e055be9b542aa5f3bdd30e4f3589163e85f93f3640060509f", size = 10281872, upload-time = "2025-12-15T05:03:05.549Z" }, - { url = "https://files.pythonhosted.org/packages/8d/f4/4ce9a05ce5ded1de3ec1c1d96cf9f9504a04e54ce0ed55cfa38619a32b8d/mypy-1.19.1-py3-none-any.whl", hash = "sha256:f1235f5ea01b7db5468d53ece6aaddf1ad0b88d9e7462b86ef96fe04995d7247", size = 2471239, upload-time = "2025-12-15T05:03:07.248Z" }, -] - [[package]] name = "mypy-extensions" version = "1.1.0" @@ -1973,13 +1927,13 @@ dev = [ { name = "mkdocs-material" }, { name = "mkdocs-redirects" }, { name = "mkdocstrings", extra = ["python"] }, - { name = "mypy" }, { name = "pillow" }, { name = "pre-commit" }, { name = "prek" }, { name = "pytest" }, { name = "pyyaml" }, { name = "ruff" }, + { name = "ty" }, { name = "typer" }, { name = "typing-extensions" }, ] @@ -2012,10 +1966,10 @@ tests = [ { name = "fastapi" }, { name = "httpx" }, { name = "jinja2" }, - { name = "mypy" }, { name = "pre-commit" }, { name = "pytest" }, { name = "ruff" }, + { name = "ty" }, { name = "typing-extensions" }, ] @@ -2042,13 +1996,13 @@ dev = [ { name = "mkdocs-material", specifier = "==9.7.4" }, { name = "mkdocs-redirects", specifier = ">=1.2.1,<1.3.0" }, { name = "mkdocstrings", extras = ["python"], specifier = "==1.0.3" }, - { name = "mypy", specifier = "==1.19.1" }, { name = "pillow", specifier = "==12.1.1" }, { name = "pre-commit", specifier = ">=2.17.0,<5.0.0" }, { name = "prek", specifier = ">=0.2.24,<1.0.0" }, { name = "pytest", specifier = ">=7.0.1,<10.0.0" }, { name = "pyyaml", specifier = ">=5.3.1,<7.0.0" }, { name = "ruff", specifier = "==0.15.5" }, + { name = "ty", specifier = ">=0.0.9" }, { name = "typer", specifier = "==0.24.1" }, { name = "typing-extensions", specifier = "==4.15.0" }, ] @@ -2081,10 +2035,10 @@ 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 = "pre-commit", specifier = ">=2.17.0,<5.0.0" }, { name = "pytest", specifier = ">=7.0.1,<10.0.0" }, { name = "ruff", specifier = "==0.15.5" }, + { name = "ty", specifier = ">=0.0.9" }, { name = "typing-extensions", specifier = "==4.15.0" }, ] @@ -2183,6 +2137,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.21" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ee/20/2ba8fd9493c89c41dfe9dbb73bc70a28b28028463bc0d2897ba8be36230a/ty-0.0.21.tar.gz", hash = "sha256:a4c2ba5d67d64df8fcdefd8b280ac1149d24a73dbda82fa953a0dff9d21400ed", size = 5297967, upload-time = "2026-03-06T01:57:13.809Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/36/70/edf38bb37517531681d1c37f5df64744e5ad02673c02eb48447eae4bea08/ty-0.0.21-py3-none-linux_armv6l.whl", hash = "sha256:7bdf2f572378de78e1f388d24691c89db51b7caf07cf90f2bfcc1d6b18b70a76", size = 10299222, upload-time = "2026-03-06T01:57:16.64Z" }, + { url = "https://files.pythonhosted.org/packages/72/62/0047b0bd19afeefbc7286f20a5f78a2aa39f92b4d89853f0d7185ab89edc/ty-0.0.21-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:7e9613994610431ab8625025bd2880dbcb77c5c9fabdd21134cda12d840a529d", size = 10130513, upload-time = "2026-03-06T01:57:29.93Z" }, + { url = "https://files.pythonhosted.org/packages/a2/20/0b93a9e91aaed23155780258cdfdb4726ef68b6985378ac069bc427291a0/ty-0.0.21-py3-none-macosx_11_0_arm64.whl", hash = "sha256:56d3b198b64dd0a19b2b66e257deaed2ecea568e722ae5352f3c6fb62027f89d", size = 9605425, upload-time = "2026-03-06T01:57:27.115Z" }, + { url = "https://files.pythonhosted.org/packages/ea/fd/9945e2fa2996a1287b1e1d7ce050e97e1f420233b271e770934bfa0880a0/ty-0.0.21-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d23d2c34f7a77d974bb08f0860ef700addc8a683d81a0319f71c08f87506cfd0", size = 10108298, upload-time = "2026-03-06T01:57:35.429Z" }, + { url = "https://files.pythonhosted.org/packages/52/e7/4ec52fcb15f3200826c9f048472c062549a05b0d1ef0b51f32d527b513c4/ty-0.0.21-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:56b01fd2519637a4ca88344f61c96225f540c98ff18bca321d4eaa7bb0f7aa2f", size = 10121556, upload-time = "2026-03-06T01:57:03.242Z" }, + { url = "https://files.pythonhosted.org/packages/ee/c0/ad457be2a8abea0f25549598bd098554540ced66229488daa0d558dad3c8/ty-0.0.21-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e9de7e11c63c6afc40f3e9ba716374add171aee7fabc70b5146a510705c6d41b", size = 10603264, upload-time = "2026-03-06T01:56:52.134Z" }, + { url = "https://files.pythonhosted.org/packages/f8/5b/2ecc7a2175243a4bcb72f5298ae41feabbb93b764bb0dc45722f3752c2c2/ty-0.0.21-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:62f7f5b235c4f7876db305c36997aea07b7af29b1a068f373d0e2547e25f32ff", size = 11196428, upload-time = "2026-03-06T01:57:32.94Z" }, + { url = "https://files.pythonhosted.org/packages/37/f5/aff507d6a901f328ef96a298032b0c11aaaf950a146ed7dd3b5bf2cd3acf/ty-0.0.21-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ee8399f7c453a425291e6688efe430cfae7ab0ac4ffd50eba9f872bf878b54f6", size = 10866355, upload-time = "2026-03-06T01:56:57.831Z" }, + { url = "https://files.pythonhosted.org/packages/be/30/822bbcb92d55b65989aa7ed06d9585f28ade9c9447369194ed4b0fb3b5b9/ty-0.0.21-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:210e7568c9f886c4d01308d751949ee714ad7ad9d7d928d2ba90d329dd880367", size = 10738177, upload-time = "2026-03-06T01:57:11.256Z" }, + { url = "https://files.pythonhosted.org/packages/57/cc/46e7991b6469e93ac2c7e533a028983e402485580150ac864c56352a3a82/ty-0.0.21-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:53508e345b11569f78b21ba8e2b4e61df38a9754947fb3cd9f2ef574367338fb", size = 10079158, upload-time = "2026-03-06T01:57:00.516Z" }, + { url = "https://files.pythonhosted.org/packages/15/c2/0bbdadfbd008240f8f1a87dc877433cb3884436097926107ccf06e618199/ty-0.0.21-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:553e43571f4a35604c36cfd07d8b61a5eb7a714e3c67f8c4ff2cf674fefbaef9", size = 10150535, upload-time = "2026-03-06T01:57:08.815Z" }, + { url = "https://files.pythonhosted.org/packages/c5/b5/2dbdb7b57b5362200ef0a39738ebd31331726328336def0143ac097ee59d/ty-0.0.21-py3-none-musllinux_1_2_i686.whl", hash = "sha256:666f6822e3b9200abfa7e95eb0ddd576460adb8d66b550c0ad2c70abc84a2048", size = 10319803, upload-time = "2026-03-06T01:57:19.106Z" }, + { url = "https://files.pythonhosted.org/packages/72/84/70e52c0b7abc7c2086f9876ef454a73b161d3125315536d8d7e911c94ca4/ty-0.0.21-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:a0854d008347ce4a5fb351af132f660a390ab2a1163444d075251d43e6f74b9b", size = 10826239, upload-time = "2026-03-06T01:57:21.727Z" }, + { url = "https://files.pythonhosted.org/packages/a1/8a/1f72480fd013bbc6cd1929002abbbcde9a0b08ead6a15154de9d7f7fa37e/ty-0.0.21-py3-none-win32.whl", hash = "sha256:bef3ab4c7b966bcc276a8ac6c11b63ba222d21355b48d471ea782c4104eee4e0", size = 9693196, upload-time = "2026-03-06T01:57:24.126Z" }, + { url = "https://files.pythonhosted.org/packages/8d/f8/1104808b875c26c640e536945753a78562d606bef4e241d9dbf3d92477f6/ty-0.0.21-py3-none-win_amd64.whl", hash = "sha256:a709d576e5bea84b745d43058d8b9cd4f27f74a0b24acb4b0cbb7d3d41e0d050", size = 10668660, upload-time = "2026-03-06T01:56:55.06Z" }, + { url = "https://files.pythonhosted.org/packages/1b/b8/25e0adc404bbf986977657b25318991f93097b49f8aea640d93c0b0db68e/ty-0.0.21-py3-none-win_arm64.whl", hash = "sha256:f72047996598ac20553fb7e21ba5741e3c82dee4e9eadf10d954551a5fe09391", size = 10104161, upload-time = "2026-03-06T01:57:06.072Z" }, +] + [[package]] name = "typer" version = "0.24.1"