From: Sebastián Ramírez Date: Fri, 26 Dec 2025 11:23:00 +0000 (-0800) Subject: ➖ Drop support for Python 3.8 (#1696) X-Git-Tag: 0.0.30~5 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=056232ab4518de2f4b0a1375985e9a81904cad63;p=thirdparty%2Ffastapi%2Fsqlmodel.git ➖ Drop support for Python 3.8 (#1696) --- diff --git a/pdm_build.py b/pdm_build.py index 23246701..33a6b267 100644 --- a/pdm_build.py +++ b/pdm_build.py @@ -1,5 +1,5 @@ import os -from typing import Any, Dict, List +from typing import Any from pdm.backend.hooks import Context @@ -9,30 +9,30 @@ TIANGOLO_BUILD_PACKAGE = os.getenv("TIANGOLO_BUILD_PACKAGE", "sqlmodel") def pdm_build_initialize(context: Context) -> None: metadata = context.config.metadata # Get custom config for the current package, from the env var - config: Dict[str, Any] = context.config.data["tool"]["tiangolo"][ + config: dict[str, Any] = context.config.data["tool"]["tiangolo"][ "_internal-slim-build" ]["packages"][TIANGOLO_BUILD_PACKAGE] - project_config: Dict[str, Any] = config["project"] + project_config: dict[str, Any] = config["project"] # Get main optional dependencies, extras - optional_dependencies: Dict[str, List[str]] = metadata.get( + optional_dependencies: dict[str, list[str]] = metadata.get( "optional-dependencies", {} ) # Get custom optional dependencies name to always include in this (non-slim) package - include_optional_dependencies: List[str] = config.get( + include_optional_dependencies: list[str] = config.get( "include-optional-dependencies", [] ) # Override main [project] configs with custom configs for this package for key, value in project_config.items(): metadata[key] = value # Get custom build config for the current package - build_config: Dict[str, Any] = ( + build_config: dict[str, Any] = ( config.get("tool", {}).get("pdm", {}).get("build", {}) ) # Override PDM build config with custom build config for this package for key, value in build_config.items(): context.config.build_config[key] = value # Get main dependencies - dependencies: List[str] = metadata.get("dependencies", []) + dependencies: list[str] = metadata.get("dependencies", []) # Add optional dependencies to the default dependencies for this (non-slim) package for include_optional in include_optional_dependencies: optional_dependencies_group = optional_dependencies.get(include_optional, []) diff --git a/pyproject.toml b/pyproject.toml index 048f3884..0a95bfab 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ name = "sqlmodel" dynamic = ["version"] description = "SQLModel, SQL databases in Python, designed for simplicity, compatibility, and robustness." readme = "README.md" -requires-python = ">=3.8" +requires-python = ">=3.9" authors = [ { name = "Sebastián Ramírez", email = "tiangolo@gmail.com" }, ] @@ -21,7 +21,6 @@ classifiers = [ "Intended Audience :: Science/Research", "Intended Audience :: System Administrators", "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", diff --git a/scripts/generate_select.py b/scripts/generate_select.py index 49c2b2b0..cbb842b3 100644 --- a/scripts/generate_select.py +++ b/scripts/generate_select.py @@ -1,7 +1,6 @@ import os from itertools import product from pathlib import Path -from typing import List, Tuple import black from jinja2 import Template @@ -21,15 +20,15 @@ class Arg(BaseModel): annotation: str -arg_groups: List[Arg] = [] +arg_groups: list[Arg] = [] -signatures: List[Tuple[List[Arg], List[str]]] = [] +signatures: list[tuple[list[Arg], list[str]]] = [] for total_args in range(2, number_of_types + 1): arg_types_tuples = product(["model", "scalar"], repeat=total_args) for arg_type_tuple in arg_types_tuples: - args: List[Arg] = [] - return_types: List[str] = [] + args: list[Arg] = [] + return_types: list[str] = [] for i, arg_type in enumerate(arg_type_tuple): if arg_type == "scalar": t_var = f"_TScalar_{i}" diff --git a/scripts/mkdocs_hooks.py b/scripts/mkdocs_hooks.py index f09e9a99..0e878946 100644 --- a/scripts/mkdocs_hooks.py +++ b/scripts/mkdocs_hooks.py @@ -1,4 +1,4 @@ -from typing import Any, List, Union +from typing import Any, Union from mkdocs.config.defaults import MkDocsConfig from mkdocs.structure.files import Files @@ -7,9 +7,9 @@ from mkdocs.structure.pages import Page def generate_renamed_section_items( - items: List[Union[Page, Section, Link]], *, config: MkDocsConfig -) -> List[Union[Page, Section, Link]]: - new_items: List[Union[Page, Section, Link]] = [] + items: list[Union[Page, Section, Link]], *, config: MkDocsConfig +) -> list[Union[Page, Section, Link]]: + new_items: list[Union[Page, Section, Link]] = [] for item in items: if isinstance(item, Section): new_title = item.title diff --git a/sqlmodel/_compat.py b/sqlmodel/_compat.py index 230f8cc3..60874149 100644 --- a/sqlmodel/_compat.py +++ b/sqlmodel/_compat.py @@ -1,20 +1,16 @@ import sys import types +from collections.abc import Generator, Mapping, Set from contextlib import contextmanager from contextvars import ContextVar from dataclasses import dataclass from typing import ( TYPE_CHECKING, - AbstractSet, + Annotated, Any, Callable, - Dict, ForwardRef, - Generator, - Mapping, Optional, - Set, - Type, TypeVar, Union, ) @@ -22,7 +18,7 @@ from typing import ( from pydantic import VERSION as P_VERSION from pydantic import BaseModel from pydantic.fields import FieldInfo -from typing_extensions import Annotated, get_args, get_origin +from typing_extensions import get_args, get_origin # Reassign variable to make it reexported for mypy PYDANTIC_VERSION = P_VERSION @@ -36,7 +32,7 @@ if TYPE_CHECKING: UnionType = getattr(types, "UnionType", Union) NoneType = type(None) T = TypeVar("T") -InstanceOrType = Union[T, Type[T]] +InstanceOrType = Union[T, type[T]] _TSQLModel = TypeVar("_TSQLModel", bound="SQLModel") @@ -49,7 +45,7 @@ class FakeMetadata: @dataclass class ObjectWithUpdateWrapper: obj: Any - update: Dict[str, Any] + update: dict[str, Any] def __getattribute__(self, __name: str) -> Any: update = super().__getattribute__("update") @@ -103,7 +99,7 @@ if IS_PYDANTIC_V2: ) -> None: model.model_config[parameter] = value # type: ignore[literal-required] - def get_model_fields(model: InstanceOrType[BaseModel]) -> Dict[str, "FieldInfo"]: + def get_model_fields(model: InstanceOrType[BaseModel]) -> dict[str, "FieldInfo"]: # TODO: refactor the usage of this function to always pass the class # not the instance, and then remove this extra check # this is for compatibility with Pydantic v3 @@ -115,7 +111,7 @@ if IS_PYDANTIC_V2: def get_fields_set( object: InstanceOrType["SQLModel"], - ) -> Union[Set[str], Callable[[BaseModel], Set[str]]]: + ) -> Union[set[str], Callable[[BaseModel], set[str]]]: return object.model_fields_set def init_pydantic_private_attrs(new_object: InstanceOrType["SQLModel"]) -> None: @@ -123,8 +119,8 @@ if IS_PYDANTIC_V2: object.__setattr__(new_object, "__pydantic_extra__", None) object.__setattr__(new_object, "__pydantic_private__", None) - def get_annotations(class_dict: Dict[str, Any]) -> Dict[str, Any]: - raw_annotations: Dict[str, Any] = class_dict.get("__annotations__", {}) + def get_annotations(class_dict: dict[str, Any]) -> dict[str, Any]: + raw_annotations: dict[str, Any] = class_dict.get("__annotations__", {}) if sys.version_info >= (3, 14) and "__annotations__" not in class_dict: # See https://github.com/pydantic/pydantic/pull/11991 from annotationlib import ( @@ -139,7 +135,7 @@ if IS_PYDANTIC_V2: ) return raw_annotations - def is_table_model_class(cls: Type[Any]) -> bool: + def is_table_model_class(cls: type[Any]) -> bool: config = getattr(cls, "model_config", {}) if config: return config.get("table", False) or False @@ -243,15 +239,15 @@ if IS_PYDANTIC_V2: include: Optional[Mapping[Union[int, str], Any]], exclude: Optional[Mapping[Union[int, str], Any]], exclude_unset: bool, - update: Optional[Dict[str, Any]] = None, - ) -> Optional[AbstractSet[str]]: # pragma: no cover + update: Optional[dict[str, Any]] = None, + ) -> Optional[Set[str]]: # pragma: no cover return None def sqlmodel_table_construct( *, self_instance: _TSQLModel, - values: Dict[str, Any], - _fields_set: Union[Set[str], None] = None, + values: dict[str, Any], + _fields_set: Union[set[str], None] = None, ) -> _TSQLModel: # Copy from Pydantic's BaseModel.construct() # Ref: https://github.com/pydantic/pydantic/blob/v2.5.2/pydantic/main.py#L198 @@ -264,8 +260,8 @@ if IS_PYDANTIC_V2: old_dict = self_instance.__dict__.copy() # End SQLModel override - fields_values: Dict[str, Any] = {} - defaults: Dict[ + fields_values: dict[str, Any] = {} + defaults: dict[ str, Any ] = {} # keeping this separate from `fields_values` helps us compute `_fields_set` for name, field in cls.model_fields.items(): @@ -279,7 +275,7 @@ if IS_PYDANTIC_V2: _fields_set = set(fields_values.keys()) fields_values.update(defaults) - _extra: Union[Dict[str, Any], None] = None + _extra: Union[dict[str, Any], None] = None if cls.model_config.get("extra") == "allow": _extra = {} for k, v in values.items(): @@ -315,13 +311,13 @@ if IS_PYDANTIC_V2: return self_instance def sqlmodel_validate( - cls: Type[_TSQLModel], + cls: type[_TSQLModel], obj: Any, *, strict: Union[bool, None] = None, from_attributes: Union[bool, None] = None, - context: Union[Dict[str, Any], None] = None, - update: Union[Dict[str, Any], None] = None, + context: Union[dict[str, Any], None] = None, + update: Union[dict[str, Any], None] = None, ) -> _TSQLModel: if not is_table_model_class(cls): new_obj: _TSQLModel = cls.__new__(cls) @@ -366,7 +362,7 @@ if IS_PYDANTIC_V2: setattr(new_obj, key, value) return new_obj - def sqlmodel_init(*, self: "SQLModel", data: Dict[str, Any]) -> None: + def sqlmodel_init(*, self: "SQLModel", data: dict[str, Any]) -> None: old_dict = self.__dict__.copy() if not is_table_model_class(self.__class__): self.__pydantic_validator__.validate_python( @@ -424,24 +420,24 @@ else: ) -> None: setattr(model.__config__, parameter, value) # type: ignore - def get_model_fields(model: InstanceOrType[BaseModel]) -> Dict[str, "FieldInfo"]: + def get_model_fields(model: InstanceOrType[BaseModel]) -> dict[str, "FieldInfo"]: return model.__fields__ # type: ignore def get_fields_set( object: InstanceOrType["SQLModel"], - ) -> Union[Set[str], Callable[[BaseModel], Set[str]]]: + ) -> Union[set[str], Callable[[BaseModel], set[str]]]: return object.__fields_set__ def init_pydantic_private_attrs(new_object: InstanceOrType["SQLModel"]) -> None: object.__setattr__(new_object, "__fields_set__", set()) - def get_annotations(class_dict: Dict[str, Any]) -> Dict[str, Any]: + def get_annotations(class_dict: dict[str, Any]) -> dict[str, Any]: return resolve_annotations( # type: ignore[no-any-return] class_dict.get("__annotations__", {}), class_dict.get("__module__", None), ) - def is_table_model_class(cls: Type[Any]) -> bool: + def is_table_model_class(cls: type[Any]) -> bool: config = getattr(cls, "__config__", None) if config: return getattr(config, "table", False) @@ -492,8 +488,8 @@ else: include: Optional[Mapping[Union[int, str], Any]], exclude: Optional[Mapping[Union[int, str], Any]], exclude_unset: bool, - update: Optional[Dict[str, Any]] = None, - ) -> Optional[AbstractSet[str]]: + update: Optional[dict[str, Any]] = None, + ) -> Optional[Set[str]]: if include is None and exclude is None and not exclude_unset: # Original in Pydantic: # return None @@ -504,7 +500,7 @@ else: self.__fields__.keys() # noqa ) # | self.__sqlmodel_relationships__.keys() - keys: AbstractSet[str] + keys: Set[str] if exclude_unset: keys = self.__fields_set__.copy() # noqa else: @@ -528,13 +524,13 @@ else: return keys def sqlmodel_validate( - cls: Type[_TSQLModel], + cls: type[_TSQLModel], obj: Any, *, strict: Union[bool, None] = None, from_attributes: Union[bool, None] = None, - context: Union[Dict[str, Any], None] = None, - update: Union[Dict[str, Any], None] = None, + context: Union[dict[str, Any], None] = None, + update: Union[dict[str, Any], None] = None, ) -> _TSQLModel: # This was SQLModel's original from_orm() for Pydantic v1 # Duplicated from Pydantic @@ -573,7 +569,7 @@ else: m._init_private_attributes() # type: ignore[attr-defined] # noqa return m - def sqlmodel_init(*, self: "SQLModel", data: Dict[str, Any]) -> None: + def sqlmodel_init(*, self: "SQLModel", data: dict[str, Any]) -> None: values, fields_set, validation_error = validate_model(self.__class__, data) # Only raise errors if not a SQLModel model if ( diff --git a/sqlmodel/ext/asyncio/session.py b/sqlmodel/ext/asyncio/session.py index ff99dff8..056737f8 100644 --- a/sqlmodel/ext/asyncio/session.py +++ b/sqlmodel/ext/asyncio/session.py @@ -1,10 +1,7 @@ +from collections.abc import Mapping, Sequence from typing import ( Any, - Dict, - Mapping, Optional, - Sequence, - Type, TypeVar, Union, cast, @@ -32,7 +29,7 @@ _TSelectParam = TypeVar("_TSelectParam", bound=Any) class AsyncSession(_AsyncSession): - sync_session_class: Type[Session] = Session + sync_session_class: type[Session] = Session sync_session: Session @overload @@ -42,7 +39,7 @@ class AsyncSession(_AsyncSession): *, params: Optional[Union[Mapping[str, Any], Sequence[Mapping[str, Any]]]] = None, execution_options: Mapping[str, Any] = util.EMPTY_DICT, - bind_arguments: Optional[Dict[str, Any]] = None, + bind_arguments: Optional[dict[str, Any]] = None, _parent_execute_state: Optional[Any] = None, _add_event: Optional[Any] = None, ) -> TupleResult[_TSelectParam]: ... @@ -54,7 +51,7 @@ class AsyncSession(_AsyncSession): *, params: Optional[Union[Mapping[str, Any], Sequence[Mapping[str, Any]]]] = None, execution_options: Mapping[str, Any] = util.EMPTY_DICT, - bind_arguments: Optional[Dict[str, Any]] = None, + bind_arguments: Optional[dict[str, Any]] = None, _parent_execute_state: Optional[Any] = None, _add_event: Optional[Any] = None, ) -> ScalarResult[_TSelectParam]: ... @@ -66,7 +63,7 @@ class AsyncSession(_AsyncSession): *, params: Optional[Union[Mapping[str, Any], Sequence[Mapping[str, Any]]]] = None, execution_options: Mapping[str, Any] = util.EMPTY_DICT, - bind_arguments: Optional[Dict[str, Any]] = None, + bind_arguments: Optional[dict[str, Any]] = None, _parent_execute_state: Optional[Any] = None, _add_event: Optional[Any] = None, ) -> CursorResult[Any]: ... @@ -82,7 +79,7 @@ class AsyncSession(_AsyncSession): *, params: Optional[Union[Mapping[str, Any], Sequence[Mapping[str, Any]]]] = None, execution_options: Mapping[str, Any] = util.EMPTY_DICT, - bind_arguments: Optional[Dict[str, Any]] = None, + bind_arguments: Optional[dict[str, Any]] = None, _parent_execute_state: Optional[Any] = None, _add_event: Optional[Any] = None, ) -> Union[ @@ -135,7 +132,7 @@ class AsyncSession(_AsyncSession): params: Optional[_CoreAnyExecuteParams] = None, *, execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, - bind_arguments: Optional[Dict[str, Any]] = None, + bind_arguments: Optional[dict[str, Any]] = None, _parent_execute_state: Optional[Any] = None, _add_event: Optional[Any] = None, ) -> Result[Any]: diff --git a/sqlmodel/main.py b/sqlmodel/main.py index d3016942..2e558647 100644 --- a/sqlmodel/main.py +++ b/sqlmodel/main.py @@ -1,26 +1,20 @@ from __future__ import annotations +import builtins import ipaddress import uuid import weakref +from collections.abc import Mapping, Sequence, Set from datetime import date, datetime, time, timedelta from decimal import Decimal from enum import Enum from pathlib import Path from typing import ( TYPE_CHECKING, - AbstractSet, Any, Callable, ClassVar, - Dict, - List, - Mapping, Optional, - Sequence, - Set, - Tuple, - Type, TypeVar, Union, cast, @@ -93,8 +87,8 @@ if TYPE_CHECKING: _T = TypeVar("_T") NoArgAnyCallable = Callable[[], Any] IncEx: TypeAlias = Union[ - Set[int], - Set[str], + set[int], + set[str], Mapping[int, Union["IncEx", bool]], Mapping[str, Union["IncEx", bool]], ] @@ -106,7 +100,7 @@ def __dataclass_transform__( eq_default: bool = True, order_default: bool = False, kw_only_default: bool = False, - field_descriptors: Tuple[Union[type, Callable[..., Any]], ...] = (()), + field_descriptors: tuple[Union[type, Callable[..., Any]], ...] = (()), ) -> Callable[[_T], _T]: return lambda a: a @@ -222,12 +216,8 @@ def Field( serialization_alias: Optional[str] = None, title: Optional[str] = None, description: Optional[str] = None, - exclude: Union[ - AbstractSet[Union[int, str]], Mapping[Union[int, str], Any], Any - ] = None, - include: Union[ - AbstractSet[Union[int, str]], Mapping[Union[int, str], Any], Any - ] = None, + exclude: Union[Set[Union[int, str]], Mapping[Union[int, str], Any], Any] = None, + include: Union[Set[Union[int, str]], Mapping[Union[int, str], Any], Any] = None, const: Optional[bool] = None, gt: Optional[float] = None, ge: Optional[float] = None, @@ -250,10 +240,10 @@ def Field( unique: Union[bool, UndefinedType] = Undefined, nullable: Union[bool, UndefinedType] = Undefined, index: Union[bool, UndefinedType] = Undefined, - sa_type: Union[Type[Any], UndefinedType] = Undefined, + sa_type: Union[type[Any], UndefinedType] = Undefined, sa_column_args: Union[Sequence[Any], UndefinedType] = Undefined, sa_column_kwargs: Union[Mapping[str, Any], UndefinedType] = Undefined, - schema_extra: Optional[Dict[str, Any]] = None, + schema_extra: Optional[dict[str, Any]] = None, ) -> Any: ... @@ -269,12 +259,8 @@ def Field( serialization_alias: Optional[str] = None, title: Optional[str] = None, description: Optional[str] = None, - exclude: Union[ - AbstractSet[Union[int, str]], Mapping[Union[int, str], Any], Any - ] = None, - include: Union[ - AbstractSet[Union[int, str]], Mapping[Union[int, str], Any], Any - ] = None, + exclude: Union[Set[Union[int, str]], Mapping[Union[int, str], Any], Any] = None, + include: Union[Set[Union[int, str]], Mapping[Union[int, str], Any], Any] = None, const: Optional[bool] = None, gt: Optional[float] = None, ge: Optional[float] = None, @@ -298,10 +284,10 @@ def Field( unique: Union[bool, UndefinedType] = Undefined, nullable: Union[bool, UndefinedType] = Undefined, index: Union[bool, UndefinedType] = Undefined, - sa_type: Union[Type[Any], UndefinedType] = Undefined, + sa_type: Union[type[Any], UndefinedType] = Undefined, sa_column_args: Union[Sequence[Any], UndefinedType] = Undefined, sa_column_kwargs: Union[Mapping[str, Any], UndefinedType] = Undefined, - schema_extra: Optional[Dict[str, Any]] = None, + schema_extra: Optional[dict[str, Any]] = None, ) -> Any: ... @@ -325,12 +311,8 @@ def Field( serialization_alias: Optional[str] = None, title: Optional[str] = None, description: Optional[str] = None, - exclude: Union[ - AbstractSet[Union[int, str]], Mapping[Union[int, str], Any], Any - ] = None, - include: Union[ - AbstractSet[Union[int, str]], Mapping[Union[int, str], Any], Any - ] = None, + exclude: Union[Set[Union[int, str]], Mapping[Union[int, str], Any], Any] = None, + include: Union[Set[Union[int, str]], Mapping[Union[int, str], Any], Any] = None, const: Optional[bool] = None, gt: Optional[float] = None, ge: Optional[float] = None, @@ -349,7 +331,7 @@ def Field( discriminator: Optional[str] = None, repr: bool = True, sa_column: Union[Column[Any], UndefinedType] = Undefined, - schema_extra: Optional[Dict[str, Any]] = None, + schema_extra: Optional[dict[str, Any]] = None, ) -> Any: ... @@ -362,12 +344,8 @@ def Field( serialization_alias: Optional[str] = None, title: Optional[str] = None, description: Optional[str] = None, - exclude: Union[ - AbstractSet[Union[int, str]], Mapping[Union[int, str], Any], Any - ] = None, - include: Union[ - AbstractSet[Union[int, str]], Mapping[Union[int, str], Any], Any - ] = None, + exclude: Union[Set[Union[int, str]], Mapping[Union[int, str], Any], Any] = None, + include: Union[Set[Union[int, str]], Mapping[Union[int, str], Any], Any] = None, const: Optional[bool] = None, gt: Optional[float] = None, ge: Optional[float] = None, @@ -391,11 +369,11 @@ def Field( unique: Union[bool, UndefinedType] = Undefined, nullable: Union[bool, UndefinedType] = Undefined, index: Union[bool, UndefinedType] = Undefined, - sa_type: Union[Type[Any], UndefinedType] = Undefined, + sa_type: Union[type[Any], UndefinedType] = Undefined, sa_column: Union[Column, UndefinedType] = Undefined, # type: ignore sa_column_args: Union[Sequence[Any], UndefinedType] = Undefined, sa_column_kwargs: Union[Mapping[str, Any], UndefinedType] = Undefined, - schema_extra: Optional[Dict[str, Any]] = None, + schema_extra: Optional[dict[str, Any]] = None, ) -> Any: current_schema_extra = schema_extra or {} # Extract possible alias settings from schema_extra so we can control precedence @@ -506,11 +484,11 @@ def Relationship( @__dataclass_transform__(kw_only_default=True, field_descriptors=(Field, FieldInfo)) class SQLModelMetaclass(ModelMetaclass, DeclarativeMeta): - __sqlmodel_relationships__: Dict[str, RelationshipInfo] + __sqlmodel_relationships__: dict[str, RelationshipInfo] model_config: SQLModelConfig - model_fields: ClassVar[Dict[str, FieldInfo]] - __config__: Type[SQLModelConfig] - __fields__: Dict[str, ModelField] # type: ignore[assignment] + model_fields: ClassVar[dict[str, FieldInfo]] + __config__: type[SQLModelConfig] + __fields__: dict[str, ModelField] # type: ignore[assignment] # Replicate SQLAlchemy def __setattr__(cls, name: str, value: Any) -> None: @@ -529,11 +507,11 @@ class SQLModelMetaclass(ModelMetaclass, DeclarativeMeta): def __new__( cls, name: str, - bases: Tuple[Type[Any], ...], - class_dict: Dict[str, Any], + bases: tuple[type[Any], ...], + class_dict: dict[str, Any], **kwargs: Any, ) -> Any: - relationships: Dict[str, RelationshipInfo] = {} + relationships: dict[str, RelationshipInfo] = {} dict_for_pydantic = {} original_annotations = get_annotations(class_dict) pydantic_annotations = {} @@ -557,7 +535,7 @@ class SQLModelMetaclass(ModelMetaclass, DeclarativeMeta): # Duplicate logic from Pydantic to filter config kwargs because if they are # passed directly including the registry Pydantic will pass them over to the # superclass causing an error - allowed_config_kwargs: Set[str] = { + allowed_config_kwargs: set[str] = { key for key in dir(BaseConfig) if not ( @@ -616,7 +594,7 @@ class SQLModelMetaclass(ModelMetaclass, DeclarativeMeta): # Override SQLAlchemy, allow both SQLAlchemy and plain Pydantic models def __init__( - cls, classname: str, bases: Tuple[type, ...], dict_: Dict[str, Any], **kw: Any + cls, classname: str, bases: tuple[type, ...], dict_: dict[str, Any], **kw: Any ) -> None: # Only one of the base classes (or the current one) should be a table model # this allows FastAPI cloning a SQLModel for the response_model without @@ -643,7 +621,7 @@ class SQLModelMetaclass(ModelMetaclass, DeclarativeMeta): relationship_to = get_relationship_to( name=rel_name, rel_info=rel_info, annotation=ann ) - rel_kwargs: Dict[str, Any] = {} + rel_kwargs: dict[str, Any] = {} if rel_info.back_populates: rel_kwargs["back_populates"] = rel_info.back_populates if rel_info.cascade_delete: @@ -659,7 +637,7 @@ class SQLModelMetaclass(ModelMetaclass, DeclarativeMeta): f"model {rel_info.link_model}" ) rel_kwargs["secondary"] = local_table - rel_args: List[Any] = [] + rel_args: list[Any] = [] if rel_info.sa_relationship_args: rel_args.extend(rel_info.sa_relationship_args) if rel_info.sa_relationship_kwargs: @@ -787,7 +765,7 @@ def get_column_from_field(field: Any) -> Column: # type: ignore args.extend(list(cast(Sequence[Any], sa_column_args))) sa_column_kwargs = getattr(field_info, "sa_column_kwargs", Undefined) if sa_column_kwargs is not Undefined: - kwargs.update(cast(Dict[Any, Any], sa_column_kwargs)) + kwargs.update(cast(dict[Any, Any], sa_column_kwargs)) return Column(sa_type, *args, **kwargs) # type: ignore @@ -802,7 +780,7 @@ class SQLModel(BaseModel, metaclass=SQLModelMetaclass, registry=default_registry # SQLAlchemy needs to set weakref(s), Pydantic will set the other slots values __slots__ = ("__weakref__",) __tablename__: ClassVar[Union[str, Callable[..., str]]] - __sqlmodel_relationships__: ClassVar[Dict[str, RelationshipProperty[Any]]] + __sqlmodel_relationships__: ClassVar[builtins.dict[str, RelationshipProperty[Any]]] __name__: ClassVar[str] metadata: ClassVar[MetaData] __allow_unmapped__ = True # https://docs.sqlalchemy.org/en/20/changelog/migration_20.html#migration-20-step-six @@ -857,7 +835,7 @@ class SQLModel(BaseModel, metaclass=SQLModelMetaclass, registry=default_registry if name not in self.__sqlmodel_relationships__: super().__setattr__(name, value) - def __repr_args__(self) -> Sequence[Tuple[Optional[str], Any]]: + def __repr_args__(self) -> Sequence[tuple[Optional[str], Any]]: # Don't show SQLAlchemy private attributes return [ (k, v) @@ -871,13 +849,13 @@ class SQLModel(BaseModel, metaclass=SQLModelMetaclass, registry=default_registry @classmethod def model_validate( # type: ignore[override] - cls: Type[_TSQLModel], + cls: type[_TSQLModel], obj: Any, *, strict: Union[bool, None] = None, from_attributes: Union[bool, None] = None, - context: Union[Dict[str, Any], None] = None, - update: Union[Dict[str, Any], None] = None, + context: Union[builtins.dict[str, Any], None] = None, + update: Union[builtins.dict[str, Any], None] = None, ) -> _TSQLModel: return sqlmodel_validate( cls=cls, @@ -904,10 +882,10 @@ class SQLModel(BaseModel, metaclass=SQLModelMetaclass, registry=default_registry warnings: Union[bool, Literal["none", "warn", "error"]] = True, fallback: Union[Callable[[Any], Any], None] = None, # v2.11 serialize_as_any: bool = False, # v2.7 - ) -> Dict[str, Any]: + ) -> builtins.dict[str, Any]: if PYDANTIC_MINOR_VERSION < (2, 11): by_alias = by_alias or False - extra_kwargs: Dict[str, Any] = {} + extra_kwargs: dict[str, Any] = {} if PYDANTIC_MINOR_VERSION >= (2, 7): extra_kwargs["context"] = context extra_kwargs["serialize_as_any"] = serialize_as_any @@ -953,7 +931,7 @@ class SQLModel(BaseModel, metaclass=SQLModelMetaclass, registry=default_registry exclude_unset: bool = False, exclude_defaults: bool = False, exclude_none: bool = False, - ) -> Dict[str, Any]: + ) -> builtins.dict[str, Any]: return self.model_dump( include=include, exclude=exclude, @@ -971,7 +949,9 @@ class SQLModel(BaseModel, metaclass=SQLModelMetaclass, registry=default_registry """ ) def from_orm( - cls: Type[_TSQLModel], obj: Any, update: Optional[Dict[str, Any]] = None + cls: type[_TSQLModel], + obj: Any, + update: Optional[builtins.dict[str, Any]] = None, ) -> _TSQLModel: return cls.model_validate(obj, update=update) @@ -983,7 +963,9 @@ class SQLModel(BaseModel, metaclass=SQLModelMetaclass, registry=default_registry """ ) def parse_obj( - cls: Type[_TSQLModel], obj: Any, update: Optional[Dict[str, Any]] = None + cls: type[_TSQLModel], + obj: Any, + update: Optional[builtins.dict[str, Any]] = None, ) -> _TSQLModel: if not IS_PYDANTIC_V2: obj = cls._enforce_dict_if_root(obj) # type: ignore[attr-defined] # noqa @@ -1004,8 +986,8 @@ class SQLModel(BaseModel, metaclass=SQLModelMetaclass, registry=default_registry include: Optional[Mapping[Union[int, str], Any]], exclude: Optional[Mapping[Union[int, str], Any]], exclude_unset: bool, - update: Optional[Dict[str, Any]] = None, - ) -> Optional[AbstractSet[str]]: + update: Optional[builtins.dict[str, Any]] = None, + ) -> Optional[Set[str]]: return _calculate_keys( self, include=include, @@ -1016,9 +998,9 @@ class SQLModel(BaseModel, metaclass=SQLModelMetaclass, registry=default_registry def sqlmodel_update( self: _TSQLModel, - obj: Union[Dict[str, Any], BaseModel], + obj: Union[builtins.dict[str, Any], BaseModel], *, - update: Union[Dict[str, Any], None] = None, + update: Union[builtins.dict[str, Any], None] = None, ) -> _TSQLModel: use_update = (update or {}).copy() if isinstance(obj, dict): diff --git a/sqlmodel/orm/session.py b/sqlmodel/orm/session.py index 9e82d48a..d6966c0e 100644 --- a/sqlmodel/orm/session.py +++ b/sqlmodel/orm/session.py @@ -1,9 +1,7 @@ +from collections.abc import Mapping, Sequence from typing import ( Any, - Dict, - Mapping, Optional, - Sequence, TypeVar, Union, overload, @@ -34,7 +32,7 @@ class Session(_Session): *, params: Optional[Union[Mapping[str, Any], Sequence[Mapping[str, Any]]]] = None, execution_options: Mapping[str, Any] = util.EMPTY_DICT, - bind_arguments: Optional[Dict[str, Any]] = None, + bind_arguments: Optional[dict[str, Any]] = None, _parent_execute_state: Optional[Any] = None, _add_event: Optional[Any] = None, ) -> TupleResult[_TSelectParam]: ... @@ -46,7 +44,7 @@ class Session(_Session): *, params: Optional[Union[Mapping[str, Any], Sequence[Mapping[str, Any]]]] = None, execution_options: Mapping[str, Any] = util.EMPTY_DICT, - bind_arguments: Optional[Dict[str, Any]] = None, + bind_arguments: Optional[dict[str, Any]] = None, _parent_execute_state: Optional[Any] = None, _add_event: Optional[Any] = None, ) -> ScalarResult[_TSelectParam]: ... @@ -58,7 +56,7 @@ class Session(_Session): *, params: Optional[Union[Mapping[str, Any], Sequence[Mapping[str, Any]]]] = None, execution_options: Mapping[str, Any] = util.EMPTY_DICT, - bind_arguments: Optional[Dict[str, Any]] = None, + bind_arguments: Optional[dict[str, Any]] = None, _parent_execute_state: Optional[Any] = None, _add_event: Optional[Any] = None, ) -> CursorResult[Any]: ... @@ -74,7 +72,7 @@ class Session(_Session): *, params: Optional[Union[Mapping[str, Any], Sequence[Mapping[str, Any]]]] = None, execution_options: Mapping[str, Any] = util.EMPTY_DICT, - bind_arguments: Optional[Dict[str, Any]] = None, + bind_arguments: Optional[dict[str, Any]] = None, _parent_execute_state: Optional[Any] = None, _add_event: Optional[Any] = None, ) -> Union[ @@ -119,7 +117,7 @@ class Session(_Session): params: Optional[_CoreAnyExecuteParams] = None, *, execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT, - bind_arguments: Optional[Dict[str, Any]] = None, + bind_arguments: Optional[dict[str, Any]] = None, _parent_execute_state: Optional[Any] = None, _add_event: Optional[Any] = None, ) -> Result[Any]: diff --git a/sqlmodel/sql/_expression_select_cls.py b/sqlmodel/sql/_expression_select_cls.py index 9fd86099..8f5469f4 100644 --- a/sqlmodel/sql/_expression_select_cls.py +++ b/sqlmodel/sql/_expression_select_cls.py @@ -1,5 +1,4 @@ from typing import ( - Tuple, TypeVar, Union, ) @@ -15,7 +14,7 @@ _T = TypeVar("_T") # Separate this class in SelectBase, Select, and SelectOfScalar so that they can share # where and having without having type overlap incompatibility in session.exec(). -class SelectBase(_Select[Tuple[_T]]): +class SelectBase(_Select[tuple[_T]]): inherit_cache = True def where(self, *whereclause: Union[_ColumnExpressionArgument[bool], bool]) -> Self: diff --git a/sqlmodel/sql/_expression_select_gen.py b/sqlmodel/sql/_expression_select_gen.py index 08aa59ad..f602732f 100644 --- a/sqlmodel/sql/_expression_select_gen.py +++ b/sqlmodel/sql/_expression_select_gen.py @@ -1,12 +1,9 @@ # WARNING: do not modify this code, it is generated by _expression_select_gen.py.jinja2 +from collections.abc import Mapping, Sequence from datetime import datetime from typing import ( Any, - Mapping, - Sequence, - Tuple, - Type, TypeVar, Union, overload, @@ -29,7 +26,7 @@ _T = TypeVar("_T") _TCCA = Union[ TypedColumnsClauseRole[_T], SQLCoreOperations[_T], - Type[_T], + type[_T], ] # Generated TypeVars start @@ -126,28 +123,28 @@ def select(__ent0: _TScalar_0) -> SelectOfScalar[_TScalar_0]: # type: ignore def select( # type: ignore __ent0: _TCCA[_T0], __ent1: _TCCA[_T1], -) -> Select[Tuple[_T0, _T1]]: ... +) -> Select[tuple[_T0, _T1]]: ... @overload def select( # type: ignore __ent0: _TCCA[_T0], entity_1: _TScalar_1, -) -> Select[Tuple[_T0, _TScalar_1]]: ... +) -> Select[tuple[_T0, _TScalar_1]]: ... @overload def select( # type: ignore entity_0: _TScalar_0, __ent1: _TCCA[_T1], -) -> Select[Tuple[_TScalar_0, _T1]]: ... +) -> Select[tuple[_TScalar_0, _T1]]: ... @overload def select( # type: ignore entity_0: _TScalar_0, entity_1: _TScalar_1, -) -> Select[Tuple[_TScalar_0, _TScalar_1]]: ... +) -> Select[tuple[_TScalar_0, _TScalar_1]]: ... @overload @@ -155,7 +152,7 @@ def select( # type: ignore __ent0: _TCCA[_T0], __ent1: _TCCA[_T1], __ent2: _TCCA[_T2], -) -> Select[Tuple[_T0, _T1, _T2]]: ... +) -> Select[tuple[_T0, _T1, _T2]]: ... @overload @@ -163,7 +160,7 @@ def select( # type: ignore __ent0: _TCCA[_T0], __ent1: _TCCA[_T1], entity_2: _TScalar_2, -) -> Select[Tuple[_T0, _T1, _TScalar_2]]: ... +) -> Select[tuple[_T0, _T1, _TScalar_2]]: ... @overload @@ -171,7 +168,7 @@ def select( # type: ignore __ent0: _TCCA[_T0], entity_1: _TScalar_1, __ent2: _TCCA[_T2], -) -> Select[Tuple[_T0, _TScalar_1, _T2]]: ... +) -> Select[tuple[_T0, _TScalar_1, _T2]]: ... @overload @@ -179,7 +176,7 @@ def select( # type: ignore __ent0: _TCCA[_T0], entity_1: _TScalar_1, entity_2: _TScalar_2, -) -> Select[Tuple[_T0, _TScalar_1, _TScalar_2]]: ... +) -> Select[tuple[_T0, _TScalar_1, _TScalar_2]]: ... @overload @@ -187,7 +184,7 @@ def select( # type: ignore entity_0: _TScalar_0, __ent1: _TCCA[_T1], __ent2: _TCCA[_T2], -) -> Select[Tuple[_TScalar_0, _T1, _T2]]: ... +) -> Select[tuple[_TScalar_0, _T1, _T2]]: ... @overload @@ -195,7 +192,7 @@ def select( # type: ignore entity_0: _TScalar_0, __ent1: _TCCA[_T1], entity_2: _TScalar_2, -) -> Select[Tuple[_TScalar_0, _T1, _TScalar_2]]: ... +) -> Select[tuple[_TScalar_0, _T1, _TScalar_2]]: ... @overload @@ -203,7 +200,7 @@ def select( # type: ignore entity_0: _TScalar_0, entity_1: _TScalar_1, __ent2: _TCCA[_T2], -) -> Select[Tuple[_TScalar_0, _TScalar_1, _T2]]: ... +) -> Select[tuple[_TScalar_0, _TScalar_1, _T2]]: ... @overload @@ -211,7 +208,7 @@ def select( # type: ignore entity_0: _TScalar_0, entity_1: _TScalar_1, entity_2: _TScalar_2, -) -> Select[Tuple[_TScalar_0, _TScalar_1, _TScalar_2]]: ... +) -> Select[tuple[_TScalar_0, _TScalar_1, _TScalar_2]]: ... @overload @@ -220,7 +217,7 @@ def select( # type: ignore __ent1: _TCCA[_T1], __ent2: _TCCA[_T2], __ent3: _TCCA[_T3], -) -> Select[Tuple[_T0, _T1, _T2, _T3]]: ... +) -> Select[tuple[_T0, _T1, _T2, _T3]]: ... @overload @@ -229,7 +226,7 @@ def select( # type: ignore __ent1: _TCCA[_T1], __ent2: _TCCA[_T2], entity_3: _TScalar_3, -) -> Select[Tuple[_T0, _T1, _T2, _TScalar_3]]: ... +) -> Select[tuple[_T0, _T1, _T2, _TScalar_3]]: ... @overload @@ -238,7 +235,7 @@ def select( # type: ignore __ent1: _TCCA[_T1], entity_2: _TScalar_2, __ent3: _TCCA[_T3], -) -> Select[Tuple[_T0, _T1, _TScalar_2, _T3]]: ... +) -> Select[tuple[_T0, _T1, _TScalar_2, _T3]]: ... @overload @@ -247,7 +244,7 @@ def select( # type: ignore __ent1: _TCCA[_T1], entity_2: _TScalar_2, entity_3: _TScalar_3, -) -> Select[Tuple[_T0, _T1, _TScalar_2, _TScalar_3]]: ... +) -> Select[tuple[_T0, _T1, _TScalar_2, _TScalar_3]]: ... @overload @@ -256,7 +253,7 @@ def select( # type: ignore entity_1: _TScalar_1, __ent2: _TCCA[_T2], __ent3: _TCCA[_T3], -) -> Select[Tuple[_T0, _TScalar_1, _T2, _T3]]: ... +) -> Select[tuple[_T0, _TScalar_1, _T2, _T3]]: ... @overload @@ -265,7 +262,7 @@ def select( # type: ignore entity_1: _TScalar_1, __ent2: _TCCA[_T2], entity_3: _TScalar_3, -) -> Select[Tuple[_T0, _TScalar_1, _T2, _TScalar_3]]: ... +) -> Select[tuple[_T0, _TScalar_1, _T2, _TScalar_3]]: ... @overload @@ -274,7 +271,7 @@ def select( # type: ignore entity_1: _TScalar_1, entity_2: _TScalar_2, __ent3: _TCCA[_T3], -) -> Select[Tuple[_T0, _TScalar_1, _TScalar_2, _T3]]: ... +) -> Select[tuple[_T0, _TScalar_1, _TScalar_2, _T3]]: ... @overload @@ -283,7 +280,7 @@ def select( # type: ignore entity_1: _TScalar_1, entity_2: _TScalar_2, entity_3: _TScalar_3, -) -> Select[Tuple[_T0, _TScalar_1, _TScalar_2, _TScalar_3]]: ... +) -> Select[tuple[_T0, _TScalar_1, _TScalar_2, _TScalar_3]]: ... @overload @@ -292,7 +289,7 @@ def select( # type: ignore __ent1: _TCCA[_T1], __ent2: _TCCA[_T2], __ent3: _TCCA[_T3], -) -> Select[Tuple[_TScalar_0, _T1, _T2, _T3]]: ... +) -> Select[tuple[_TScalar_0, _T1, _T2, _T3]]: ... @overload @@ -301,7 +298,7 @@ def select( # type: ignore __ent1: _TCCA[_T1], __ent2: _TCCA[_T2], entity_3: _TScalar_3, -) -> Select[Tuple[_TScalar_0, _T1, _T2, _TScalar_3]]: ... +) -> Select[tuple[_TScalar_0, _T1, _T2, _TScalar_3]]: ... @overload @@ -310,7 +307,7 @@ def select( # type: ignore __ent1: _TCCA[_T1], entity_2: _TScalar_2, __ent3: _TCCA[_T3], -) -> Select[Tuple[_TScalar_0, _T1, _TScalar_2, _T3]]: ... +) -> Select[tuple[_TScalar_0, _T1, _TScalar_2, _T3]]: ... @overload @@ -319,7 +316,7 @@ def select( # type: ignore __ent1: _TCCA[_T1], entity_2: _TScalar_2, entity_3: _TScalar_3, -) -> Select[Tuple[_TScalar_0, _T1, _TScalar_2, _TScalar_3]]: ... +) -> Select[tuple[_TScalar_0, _T1, _TScalar_2, _TScalar_3]]: ... @overload @@ -328,7 +325,7 @@ def select( # type: ignore entity_1: _TScalar_1, __ent2: _TCCA[_T2], __ent3: _TCCA[_T3], -) -> Select[Tuple[_TScalar_0, _TScalar_1, _T2, _T3]]: ... +) -> Select[tuple[_TScalar_0, _TScalar_1, _T2, _T3]]: ... @overload @@ -337,7 +334,7 @@ def select( # type: ignore entity_1: _TScalar_1, __ent2: _TCCA[_T2], entity_3: _TScalar_3, -) -> Select[Tuple[_TScalar_0, _TScalar_1, _T2, _TScalar_3]]: ... +) -> Select[tuple[_TScalar_0, _TScalar_1, _T2, _TScalar_3]]: ... @overload @@ -346,7 +343,7 @@ def select( # type: ignore entity_1: _TScalar_1, entity_2: _TScalar_2, __ent3: _TCCA[_T3], -) -> Select[Tuple[_TScalar_0, _TScalar_1, _TScalar_2, _T3]]: ... +) -> Select[tuple[_TScalar_0, _TScalar_1, _TScalar_2, _T3]]: ... @overload @@ -355,7 +352,7 @@ def select( # type: ignore entity_1: _TScalar_1, entity_2: _TScalar_2, entity_3: _TScalar_3, -) -> Select[Tuple[_TScalar_0, _TScalar_1, _TScalar_2, _TScalar_3]]: ... +) -> Select[tuple[_TScalar_0, _TScalar_1, _TScalar_2, _TScalar_3]]: ... # Generated overloads end diff --git a/sqlmodel/sql/_expression_select_gen.py.jinja2 b/sqlmodel/sql/_expression_select_gen.py.jinja2 index ef838e41..ad0b59ae 100644 --- a/sqlmodel/sql/_expression_select_gen.py.jinja2 +++ b/sqlmodel/sql/_expression_select_gen.py.jinja2 @@ -1,10 +1,7 @@ +from collections.abc import Mapping, Sequence from datetime import datetime from typing import ( Any, - Mapping, - Sequence, - Tuple, - Type, TypeVar, Union, overload, @@ -27,7 +24,7 @@ _T = TypeVar("_T") _TCCA = Union[ TypedColumnsClauseRole[_T], SQLCoreOperations[_T], - Type[_T], + type[_T], ] # Generated TypeVars start @@ -71,7 +68,7 @@ def select(__ent0: _TScalar_0) -> SelectOfScalar[_TScalar_0]: # type: ignore @overload def select( # type: ignore {% for arg in signature[0] %}{{ arg.name }}: {{ arg.annotation }}, {% endfor %} - ) -> Select[Tuple[{%for ret in signature[1] %}{{ ret }} {% if not loop.last %}, {% endif %}{% endfor %}]]: ... + ) -> Select[tuple[{%for ret in signature[1] %}{{ ret }} {% if not loop.last %}, {% endif %}{% endfor %}]]: ... {% endfor %} diff --git a/sqlmodel/sql/expression.py b/sqlmodel/sql/expression.py index f4317476..77323361 100644 --- a/sqlmodel/sql/expression.py +++ b/sqlmodel/sql/expression.py @@ -1,11 +1,7 @@ +from collections.abc import Iterable, Mapping, Sequence from typing import ( Any, - Iterable, - Mapping, Optional, - Sequence, - Tuple, - Type, TypeVar, Union, ) @@ -46,7 +42,7 @@ from ._expression_select_gen import select as select _T = TypeVar("_T") -_TypeEngineArgument = Union[Type[TypeEngine[_T]], TypeEngine[_T]] +_TypeEngineArgument = Union[type[TypeEngine[_T]], TypeEngine[_T]] # Redefine operatos that would only take a column expresion to also take the (virtual) # types of Pydantic models, e.g. str instead of only Mapped[str]. @@ -94,7 +90,7 @@ def not_(clause: Union[_ColumnExpressionArgument[_T], _T]) -> ColumnElement[_T]: def case( *whens: Union[ - Tuple[Union[_ColumnExpressionArgument[bool], bool], Any], Mapping[Any, Any] + tuple[Union[_ColumnExpressionArgument[bool], bool], Any], Mapping[Any, Any] ], value: Optional[Any] = None, else_: Optional[Any] = None, @@ -181,8 +177,8 @@ def over( Any, ] ] = None, - range_: Optional[Tuple[Optional[int], Optional[int]]] = None, - rows: Optional[Tuple[Optional[int], Optional[int]]] = None, + range_: Optional[tuple[Optional[int], Optional[int]]] = None, + rows: Optional[tuple[Optional[int], Optional[int]]] = None, ) -> Over[_T]: return sqlalchemy.over( element, partition_by=partition_by, order_by=order_by, range_=range_, rows=rows @@ -192,7 +188,7 @@ def over( def tuple_( *clauses: Union[_ColumnExpressionArgument[Any], Any], types: Optional[Sequence["_TypeEngineArgument[Any]"]] = None, -) -> Tuple[Any, ...]: +) -> tuple[Any, ...]: return sqlalchemy.tuple_(*clauses, types=types) # type: ignore[return-value] diff --git a/tests/conftest.py b/tests/conftest.py index d8da629d..39597095 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,9 +1,10 @@ import shutil import subprocess import sys +from collections.abc import Generator from dataclasses import dataclass, field from pathlib import Path -from typing import Any, Callable, Dict, Generator, List, Union +from typing import Any, Callable, Union from unittest.mock import patch import pytest @@ -53,10 +54,10 @@ def coverage_run(*, module: str, cwd: Union[str, Path]) -> subprocess.CompletedP def get_testing_print_function( - calls: List[List[Union[str, Dict[str, Any]]]], + calls: list[list[Union[str, dict[str, Any]]]], ) -> Callable[..., Any]: def new_print(*args: Any) -> None: - data: List[Any] = [] + data: list[Any] = [] for arg in args: if isinstance(arg, BaseModel): data.append(arg.model_dump()) @@ -75,7 +76,7 @@ def get_testing_print_function( @dataclass class PrintMock: - calls: List[Any] = field(default_factory=list) + calls: list[Any] = field(default_factory=list) @pytest.fixture(name="print_mock") diff --git a/tests/test_aliases.py b/tests/test_aliases.py index 2ac9a5ac..cbd5030c 100644 --- a/tests/test_aliases.py +++ b/tests/test_aliases.py @@ -1,4 +1,4 @@ -from typing import Type, Union +from typing import Union import pytest from pydantic import BaseModel, ValidationError @@ -42,14 +42,14 @@ else: @pytest.mark.parametrize("model", [PydanticUser, SQLModelUser]) -def test_create_with_field_name(model: Union[Type[PydanticUser], Type[SQLModelUser]]): +def test_create_with_field_name(model: Union[type[PydanticUser], type[SQLModelUser]]): with pytest.raises(ValidationError): model(full_name="Alice") @pytest.mark.parametrize("model", [PydanticUserWithConfig, SQLModelUserWithConfig]) def test_create_with_field_name_with_config( - model: Union[Type[PydanticUserWithConfig], Type[SQLModelUserWithConfig]], + model: Union[type[PydanticUserWithConfig], type[SQLModelUserWithConfig]], ): user = model(full_name="Alice") assert user.full_name == "Alice" @@ -61,10 +61,10 @@ def test_create_with_field_name_with_config( ) def test_create_with_alias( model: Union[ - Type[PydanticUser], - Type[SQLModelUser], - Type[PydanticUserWithConfig], - Type[SQLModelUserWithConfig], + type[PydanticUser], + type[SQLModelUser], + type[PydanticUserWithConfig], + type[SQLModelUserWithConfig], ], ): user = model(fullName="Bob") # using alias @@ -73,7 +73,7 @@ def test_create_with_alias( @pytest.mark.parametrize("model", [PydanticUserWithConfig, SQLModelUserWithConfig]) def test_create_with_both_prefers_alias( - model: Union[Type[PydanticUserWithConfig], Type[SQLModelUserWithConfig]], + model: Union[type[PydanticUserWithConfig], type[SQLModelUserWithConfig]], ): user = model(full_name="IGNORED", fullName="Charlie") assert user.full_name == "Charlie" # alias should take precedence @@ -81,7 +81,7 @@ def test_create_with_both_prefers_alias( @pytest.mark.parametrize("model", [PydanticUser, SQLModelUser]) def test_dict_default_uses_field_names( - model: Union[Type[PydanticUser], Type[SQLModelUser]], + model: Union[type[PydanticUser], type[SQLModelUser]], ): user = model(fullName="Dana") if IS_PYDANTIC_V2 or isinstance(user, SQLModel): @@ -95,7 +95,7 @@ def test_dict_default_uses_field_names( @pytest.mark.parametrize("model", [PydanticUser, SQLModelUser]) def test_dict_by_alias_uses_aliases( - model: Union[Type[PydanticUser], Type[SQLModelUser]], + model: Union[type[PydanticUser], type[SQLModelUser]], ): user = model(fullName="Dana") if IS_PYDANTIC_V2 or isinstance(user, SQLModel): @@ -109,7 +109,7 @@ def test_dict_by_alias_uses_aliases( @pytest.mark.parametrize("model", [PydanticUser, SQLModelUser]) def test_json_by_alias( - model: Union[Type[PydanticUser], Type[SQLModelUser]], + model: Union[type[PydanticUser], type[SQLModelUser]], ): user = model(fullName="Frank") if IS_PYDANTIC_V2: @@ -156,7 +156,7 @@ def test_serialization_alias_runtimeerror_pydantic_v1(): @needs_pydanticv2 @pytest.mark.parametrize("model", [PydanticUserV2, SQLModelUserV2]) def test_create_with_validation_alias( - model: Union[Type[PydanticUserV2], Type[SQLModelUserV2]], + model: Union[type[PydanticUserV2], type[SQLModelUserV2]], ): user = model(firstName="John") assert user.first_name == "John" @@ -165,7 +165,7 @@ def test_create_with_validation_alias( @needs_pydanticv2 @pytest.mark.parametrize("model", [PydanticUserV2, SQLModelUserV2]) def test_serialize_with_serialization_alias( - model: Union[Type[PydanticUserV2], Type[SQLModelUserV2]], + model: Union[type[PydanticUserV2], type[SQLModelUserV2]], ): user = model(firstName="Jane") data = user.model_dump(by_alias=True) diff --git a/tests/test_field_sa_relationship.py b/tests/test_field_sa_relationship.py index 022a100a..c3f80302 100644 --- a/tests/test_field_sa_relationship.py +++ b/tests/test_field_sa_relationship.py @@ -1,4 +1,4 @@ -from typing import List, Optional +from typing import Optional import pytest from sqlalchemy.orm import relationship @@ -13,7 +13,7 @@ def test_sa_relationship_no_args() -> None: name: str = Field(index=True) headquarters: str - heroes: List["Hero"] = Relationship( + heroes: list["Hero"] = Relationship( back_populates="team", sa_relationship_args=["Hero"], sa_relationship=relationship("Hero", back_populates="team"), @@ -37,7 +37,7 @@ def test_sa_relationship_no_kwargs() -> None: name: str = Field(index=True) headquarters: str - heroes: List["Hero"] = Relationship( + heroes: list["Hero"] = Relationship( back_populates="team", sa_relationship_kwargs={"lazy": "selectin"}, sa_relationship=relationship("Hero", back_populates="team"), diff --git a/tests/test_main.py b/tests/test_main.py index 60d5c40e..c1508d18 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -1,4 +1,4 @@ -from typing import List, Optional +from typing import Optional import pytest from sqlalchemy.exc import IntegrityError @@ -99,7 +99,7 @@ def test_sa_relationship_property(clear_sqlmodel): class Team(SQLModel, table=True): id: Optional[int] = Field(default=None, primary_key=True) name: str = Field(unique=True) - heroes: List["Hero"] = Relationship( # noqa: F821 + heroes: list["Hero"] = Relationship( # noqa: F821 sa_relationship=RelationshipProperty("Hero", back_populates="team") ) diff --git a/tests/test_ondelete_raises.py b/tests/test_ondelete_raises.py index cbcab4ca..761b8799 100644 --- a/tests/test_ondelete_raises.py +++ b/tests/test_ondelete_raises.py @@ -1,4 +1,4 @@ -from typing import Any, List, Union +from typing import Any, Union import pytest from sqlmodel import Field, Relationship, SQLModel @@ -10,7 +10,7 @@ def test_ondelete_requires_nullable(clear_sqlmodel: Any) -> None: class Team(SQLModel, table=True): id: Union[int, None] = Field(default=None, primary_key=True) - heroes: List["Hero"] = Relationship( + heroes: list["Hero"] = Relationship( back_populates="team", passive_deletes="all" ) diff --git a/tests/test_sqlalchemy_type_errors.py b/tests/test_sqlalchemy_type_errors.py index e211c46a..cc3326b5 100644 --- a/tests/test_sqlalchemy_type_errors.py +++ b/tests/test_sqlalchemy_type_errors.py @@ -1,4 +1,4 @@ -from typing import Any, Dict, List, Optional, Union +from typing import Any, Optional, Union import pytest from sqlmodel import Field, SQLModel @@ -9,7 +9,7 @@ def test_type_list_breaks() -> None: class Hero(SQLModel, table=True): id: Optional[int] = Field(default=None, primary_key=True) - tags: List[str] + tags: list[str] def test_type_dict_breaks() -> None: @@ -17,7 +17,7 @@ def test_type_dict_breaks() -> None: class Hero(SQLModel, table=True): id: Optional[int] = Field(default=None, primary_key=True) - tags: Dict[str, Any] + tags: dict[str, Any] def test_type_union_breaks() -> None: diff --git a/tests/test_tutorial/test_automatic_id_none_refresh/test_tutorial001_tutorial002.py b/tests/test_tutorial/test_automatic_id_none_refresh/test_tutorial001_tutorial002.py index b2c452f9..cd285ae4 100644 --- a/tests/test_tutorial/test_automatic_id_none_refresh/test_tutorial001_tutorial002.py +++ b/tests/test_tutorial/test_automatic_id_none_refresh/test_tutorial001_tutorial002.py @@ -1,6 +1,6 @@ import importlib from types import ModuleType -from typing import Any, Dict, List, Union +from typing import Any, Union import pytest from sqlmodel import create_engine @@ -8,7 +8,7 @@ from sqlmodel import create_engine from tests.conftest import PrintMock, needs_py310 -def check_calls(calls: List[List[Union[str, Dict[str, Any]]]]) -> None: +def check_calls(calls: list[list[Union[str, dict[str, Any]]]]) -> None: assert calls[0] == ["Before interacting with the database"] assert calls[1] == [ "Hero 1:", diff --git a/tests/test_tutorial/test_select/test_tutorial001_tutorial002.py b/tests/test_tutorial/test_select/test_tutorial001_tutorial002.py index 3dc5c186..4d28303d 100644 --- a/tests/test_tutorial/test_select/test_tutorial001_tutorial002.py +++ b/tests/test_tutorial/test_select/test_tutorial001_tutorial002.py @@ -1,6 +1,6 @@ import importlib from types import ModuleType -from typing import Any, Dict, List, Union +from typing import Any, Union import pytest from sqlmodel import create_engine @@ -8,7 +8,7 @@ from sqlmodel import create_engine from ...conftest import PrintMock, needs_py310 -def check_calls(calls: List[List[Union[str, Dict[str, Any]]]]): +def check_calls(calls: list[list[Union[str, dict[str, Any]]]]): assert calls[0][0] == { "name": "Deadpond", "secret_name": "Dive Wilson", diff --git a/tests/test_tutorial/test_select/test_tutorial003_tutorial004.py b/tests/test_tutorial/test_select/test_tutorial003_tutorial004.py index e64d5f8b..e8e3daf1 100644 --- a/tests/test_tutorial/test_select/test_tutorial003_tutorial004.py +++ b/tests/test_tutorial/test_select/test_tutorial003_tutorial004.py @@ -1,6 +1,6 @@ import importlib from types import ModuleType -from typing import Any, Dict, List, Union +from typing import Any, Union import pytest from sqlmodel import create_engine @@ -8,7 +8,7 @@ from sqlmodel import create_engine from ...conftest import PrintMock, needs_py310 -def check_calls(calls: List[List[Union[str, Dict[str, Any]]]]): +def check_calls(calls: list[list[Union[str, dict[str, Any]]]]): assert calls[0][0] == [ { "name": "Deadpond",