diff --git a/pyproject.toml b/pyproject.toml index 621f889..885ce31 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -124,6 +124,7 @@ select = [ "I", # isort "N", # pep8-naming "S", # flake8-bandit + "UP", # pyupgrade "RUF", # ruff-specific-rules ] # Ignoring rules problematic with formatter diff --git a/sqlalchemy_bind_manager/_bind_manager.py b/sqlalchemy_bind_manager/_bind_manager.py index 50cef97..9124a2a 100644 --- a/sqlalchemy_bind_manager/_bind_manager.py +++ b/sqlalchemy_bind_manager/_bind_manager.py @@ -20,7 +20,8 @@ import atexit import weakref -from typing import ClassVar, Mapping, MutableMapping, Union +from collections.abc import Mapping, MutableMapping +from typing import ClassVar from pydantic import BaseModel, ConfigDict from sqlalchemy import MetaData, create_engine @@ -46,8 +47,8 @@ class SQLAlchemyConfig(BaseModel): """ engine_url: str - engine_options: Union[dict, None] = None - session_options: Union[dict, None] = None + engine_options: dict | None = None + session_options: dict | None = None async_engine: bool = False @@ -73,15 +74,12 @@ class SQLAlchemyAsyncBind(BaseModel): class SQLAlchemyBindManager: - __binds: MutableMapping[str, Union[SQLAlchemyBind, SQLAlchemyAsyncBind]] + __binds: MutableMapping[str, SQLAlchemyBind | SQLAlchemyAsyncBind] _instances: ClassVar[weakref.WeakSet["SQLAlchemyBindManager"]] = weakref.WeakSet() def __init__( self, - config: Union[ - Mapping[str, SQLAlchemyConfig], - SQLAlchemyConfig, - ], + config: Mapping[str, SQLAlchemyConfig] | SQLAlchemyConfig, ) -> None: self.__binds = {} if isinstance(config, Mapping): @@ -181,7 +179,7 @@ def get_bind_mappers_metadata(self) -> Mapping[str, MetaData]: def get_bind( self, bind_name: str = DEFAULT_BIND_NAME - ) -> Union[SQLAlchemyBind, SQLAlchemyAsyncBind]: + ) -> SQLAlchemyBind | SQLAlchemyAsyncBind: """ Returns a bind object by name. @@ -193,7 +191,7 @@ def get_bind( except KeyError: raise NotInitializedBindError("Bind not initialized") - def get_binds(self) -> Mapping[str, Union[SQLAlchemyBind, SQLAlchemyAsyncBind]]: + def get_binds(self) -> Mapping[str, SQLAlchemyBind | SQLAlchemyAsyncBind]: """ Returns all the registered bind objects. @@ -210,9 +208,7 @@ def get_mapper(self, bind_name: str = DEFAULT_BIND_NAME) -> registry: """ return self.get_bind(bind_name).registry_mapper - def get_session( - self, bind_name: str = DEFAULT_BIND_NAME - ) -> Union[Session, AsyncSession]: + def get_session(self, bind_name: str = DEFAULT_BIND_NAME) -> Session | AsyncSession: """ Returns a SQLAlchemy Session object, ready to be used either directly or as a context manager diff --git a/sqlalchemy_bind_manager/_repository/abstract.py b/sqlalchemy_bind_manager/_repository/abstract.py index d4dba3a..e44affb 100644 --- a/sqlalchemy_bind_manager/_repository/abstract.py +++ b/sqlalchemy_bind_manager/_repository/abstract.py @@ -18,15 +18,11 @@ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # DEALINGS IN THE SOFTWARE. +from collections.abc import Iterable, Mapping from typing import ( Any, - Iterable, - List, Literal, - Mapping, Protocol, - Tuple, - Union, ) from .common import ( @@ -48,7 +44,7 @@ async def get(self, identifier: PRIMARY_KEY) -> MODEL: """ ... - async def get_many(self, identifiers: Iterable[PRIMARY_KEY]) -> List[MODEL]: + async def get_many(self, identifiers: Iterable[PRIMARY_KEY]) -> list[MODEL]: """Get a list of models by primary keys. :param identifiers: A list of primary keys @@ -88,11 +84,9 @@ async def delete_many(self, instances: Iterable[MODEL]) -> None: async def find( self, - search_params: Union[Mapping[str, Any], None] = None, - order_by: Union[ - Iterable[Union[str, Tuple[str, Literal["asc", "desc"]]]], None - ] = None, - ) -> List[MODEL]: + search_params: Mapping[str, Any] | None = None, + order_by: Iterable[str | tuple[str, Literal["asc", "desc"]]] | None = None, + ) -> list[MODEL]: """Find models using filters. E.g. @@ -116,10 +110,8 @@ async def paginated_find( self, items_per_page: int, page: int = 1, - search_params: Union[Mapping[str, Any], None] = None, - order_by: Union[ - Iterable[Union[str, Tuple[str, Literal["asc", "desc"]]]], None - ] = None, + search_params: Mapping[str, Any] | None = None, + order_by: Iterable[str | tuple[str, Literal["asc", "desc"]]] | None = None, ) -> PaginatedResult[MODEL]: """Find models using filters and limit/offset pagination. Returned results do include pagination metadata. @@ -152,9 +144,9 @@ async def paginated_find( async def cursor_paginated_find( self, items_per_page: int, - cursor_reference: Union[CursorReference, None] = None, + cursor_reference: CursorReference | None = None, is_before_cursor: bool = False, - search_params: Union[Mapping[str, Any], None] = None, + search_params: Mapping[str, Any] | None = None, ) -> CursorPaginatedResult[MODEL]: """Find models using filters and cursor based pagination. Returned results do include pagination metadata. @@ -194,7 +186,7 @@ def get(self, identifier: PRIMARY_KEY) -> MODEL: """ ... - def get_many(self, identifiers: Iterable[PRIMARY_KEY]) -> List[MODEL]: + def get_many(self, identifiers: Iterable[PRIMARY_KEY]) -> list[MODEL]: """Get a list of models by primary keys. :param identifiers: A list of primary keys @@ -234,11 +226,9 @@ def delete_many(self, instances: Iterable[MODEL]) -> None: def find( self, - search_params: Union[Mapping[str, Any], None] = None, - order_by: Union[ - Iterable[Union[str, Tuple[str, Literal["asc", "desc"]]]], None - ] = None, - ) -> List[MODEL]: + search_params: Mapping[str, Any] | None = None, + order_by: Iterable[str | tuple[str, Literal["asc", "desc"]]] | None = None, + ) -> list[MODEL]: """Find models using filters. E.g. @@ -262,10 +252,8 @@ def paginated_find( self, items_per_page: int, page: int = 1, - search_params: Union[Mapping[str, Any], None] = None, - order_by: Union[ - Iterable[Union[str, Tuple[str, Literal["asc", "desc"]]]], None - ] = None, + search_params: Mapping[str, Any] | None = None, + order_by: Iterable[str | tuple[str, Literal["asc", "desc"]]] | None = None, ) -> PaginatedResult[MODEL]: """Find models using filters and limit/offset pagination. Returned results do include pagination metadata. @@ -298,9 +286,9 @@ def paginated_find( def cursor_paginated_find( self, items_per_page: int, - cursor_reference: Union[CursorReference, None] = None, + cursor_reference: CursorReference | None = None, is_before_cursor: bool = False, - search_params: Union[Mapping[str, Any], None] = None, + search_params: Mapping[str, Any] | None = None, ) -> CursorPaginatedResult[MODEL]: """Find models using filters and cursor based pagination. Returned results do include pagination metadata. diff --git a/sqlalchemy_bind_manager/_repository/async_.py b/sqlalchemy_bind_manager/_repository/async_.py index 243b6c5..fef131f 100644 --- a/sqlalchemy_bind_manager/_repository/async_.py +++ b/sqlalchemy_bind_manager/_repository/async_.py @@ -18,18 +18,12 @@ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # DEALINGS IN THE SOFTWARE. +from collections.abc import AsyncIterator, Iterable, Mapping from contextlib import asynccontextmanager from typing import ( Any, - AsyncIterator, Generic, - Iterable, - List, Literal, - Mapping, - Tuple, - Type, - Union, ) from sqlalchemy import select @@ -56,13 +50,13 @@ class SQLAlchemyAsyncRepository( BaseRepository[MODEL], ): _session_handler: AsyncSessionHandler - _external_session: Union[AsyncSession, None] + _external_session: AsyncSession | None def __init__( self, - bind: Union[SQLAlchemyAsyncBind, None] = None, - session: Union[AsyncSession, None] = None, - model_class: Union[Type[MODEL], None] = None, + bind: SQLAlchemyAsyncBind | None = None, + session: AsyncSession | None = None, + model_class: type[MODEL] | None = None, ) -> None: super().__init__(model_class=model_class) if not (bool(bind) ^ bool(session)): @@ -86,7 +80,7 @@ async def get(self, identifier: PRIMARY_KEY) -> MODEL: raise ModelNotFoundError("No rows found for provided primary key.") return model - async def get_many(self, identifiers: Iterable[PRIMARY_KEY]) -> List[MODEL]: + async def get_many(self, identifiers: Iterable[PRIMARY_KEY]) -> list[MODEL]: """Get a list of models by primary keys. :param identifiers: A list of primary keys @@ -145,11 +139,9 @@ async def delete_many(self, instances: Iterable[MODEL]) -> None: async def find( self, - search_params: Union[Mapping[str, Any], None] = None, - order_by: Union[ - Iterable[Union[str, Tuple[str, Literal["asc", "desc"]]]], None - ] = None, - ) -> List[MODEL]: + search_params: Mapping[str, Any] | None = None, + order_by: Iterable[str | tuple[str, Literal["asc", "desc"]]] | None = None, + ) -> list[MODEL]: """Find models using filters. E.g. @@ -177,10 +169,8 @@ async def paginated_find( self, items_per_page: int, page: int = 1, - search_params: Union[Mapping[str, Any], None] = None, - order_by: Union[ - Iterable[Union[str, Tuple[str, Literal["asc", "desc"]]]], None - ] = None, + search_params: Mapping[str, Any] | None = None, + order_by: Iterable[str | tuple[str, Literal["asc", "desc"]]] | None = None, ) -> PaginatedResult[MODEL]: """Find models using filters and limit/offset pagination. Returned results do include pagination metadata. @@ -229,9 +219,9 @@ async def paginated_find( async def cursor_paginated_find( self, items_per_page: int, - cursor_reference: Union[CursorReference, None] = None, + cursor_reference: CursorReference | None = None, is_before_cursor: bool = False, - search_params: Union[Mapping[str, Any], None] = None, + search_params: Mapping[str, Any] | None = None, ) -> CursorPaginatedResult[MODEL]: """Find models using filters and cursor based pagination. Returned results do include pagination metadata. diff --git a/sqlalchemy_bind_manager/_repository/base_repository.py b/sqlalchemy_bind_manager/_repository/base_repository.py index 0ce6dd9..abe2383 100644 --- a/sqlalchemy_bind_manager/_repository/base_repository.py +++ b/sqlalchemy_bind_manager/_repository/base_repository.py @@ -19,17 +19,11 @@ # DEALINGS IN THE SOFTWARE. from abc import ABC +from collections.abc import Callable, Iterable, Mapping from typing import ( Any, - Callable, - Dict, Generic, - Iterable, Literal, - Mapping, - Tuple, - Type, - Union, ) from sqlalchemy import asc, desc, func, select @@ -48,9 +42,9 @@ class BaseRepository(Generic[MODEL], ABC): _max_query_limit: int = 50 - _model: Type[MODEL] + _model: type[MODEL] - def __init__(self, model_class: Union[Type[MODEL], None] = None) -> None: + def __init__(self, model_class: type[MODEL] | None = None) -> None: if getattr(self, "_model", None) is None and model_class is not None: self._model = model_class @@ -63,7 +57,7 @@ def __init__(self, model_class: Union[Type[MODEL], None] = None) -> None: " or in the `_model` class property." ) - def _is_mapped_class(self, class_: Type[MODEL]) -> bool: + def _is_mapped_class(self, class_: type[MODEL]) -> bool: """Checks if the class is mapped in SQLAlchemy. :param class_: the model class @@ -116,7 +110,7 @@ def _filter_select(self, stmt: Select, search_params: Mapping[str, Any]) -> Sele def _filter_order_by( self, stmt: Select, - order_by: Iterable[Union[str, Tuple[str, Literal["asc", "desc"]]]], + order_by: Iterable[str | tuple[str, Literal["asc", "desc"]]], ) -> Select: """Build the query ordering clauses from submitted parameters. @@ -131,7 +125,7 @@ def _filter_order_by( :param order_by: a list of columns, or tuples (column, direction) :return: The filtered query """ - _order_funcs: Dict[Literal["asc", "desc"], Callable] = { + _order_funcs: dict[Literal["asc", "desc"], Callable] = { "desc": desc, "asc": asc, } @@ -150,10 +144,8 @@ def _filter_order_by( def _find_query( self, - search_params: Union[Mapping[str, Any], None] = None, - order_by: Union[ - Iterable[Union[str, Tuple[str, Literal["asc", "desc"]]]], None - ] = None, + search_params: Mapping[str, Any] | None = None, + order_by: Iterable[str | tuple[str, Literal["asc", "desc"]]] | None = None, ) -> Select: """Build a query with column filters and orders. @@ -217,7 +209,7 @@ def _paginate_query_by_page( def _cursor_paginated_query( self, stmt: Select, - cursor_reference: Union[CursorReference, None], + cursor_reference: CursorReference | None, is_before_cursor: bool = False, items_per_page: int = _max_query_limit, ) -> Select: @@ -229,7 +221,7 @@ def _cursor_paginated_query( :type stmt: Select :param cursor_reference: A cursor reference containing ordering column and threshold value - :type cursor_reference: Union[CursorReference, None] + :type cursor_reference: CursorReference | None :param is_before_cursor: If True it will return items before the cursor, otherwise items after :type is_before_cursor: bool @@ -277,7 +269,7 @@ def _cursor_pagination_slice_query( :type stmt: Select :param cursor_reference: A cursor reference containing ordering column and threshold value - :type cursor_reference: Union[CursorReference, None] + :type cursor_reference: CursorReference | None :param is_before_cursor: If True it will return items before the cursor, otherwise items after :type is_before_cursor: bool @@ -311,7 +303,7 @@ def _cursor_pagination_previous_item_query( :type stmt: Select :param cursor_reference: A cursor reference containing ordering column and threshold value - :type cursor_reference: Union[CursorReference, None] + :type cursor_reference: CursorReference | None :param is_before_cursor: If True it will return items before the cursor, otherwise items after :type is_before_cursor: bool diff --git a/sqlalchemy_bind_manager/_repository/common.py b/sqlalchemy_bind_manager/_repository/common.py index 8a2abef..9008276 100644 --- a/sqlalchemy_bind_manager/_repository/common.py +++ b/sqlalchemy_bind_manager/_repository/common.py @@ -18,14 +18,14 @@ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # DEALINGS IN THE SOFTWARE. -from typing import Generic, List, Type, TypeVar, Union +from typing import Generic, TypeVar from uuid import UUID from pydantic import BaseModel, StrictInt, StrictStr from sqlalchemy import inspect MODEL = TypeVar("MODEL") -PRIMARY_KEY = Union[str, int, tuple, dict, UUID] +PRIMARY_KEY = str | int | tuple | dict | UUID # Constrained rather than bound: a bound TypeVar would happily bind to the # union of the constraints, which lets mismatched operands (e.g. `str >= UUID`) @@ -35,7 +35,7 @@ CURSOR_VALUE = TypeVar("CURSOR_VALUE", StrictStr, StrictInt, UUID) -def get_model_pk_name(model_class: Type) -> str: +def get_model_pk_name(model_class: type) -> str: """Retrieves the primary key column name from a SQLAlchemy model class. :param model_class: A SQLAlchemy model class @@ -79,12 +79,12 @@ class PaginatedResult(BaseModel, Generic[MODEL]): The result of a paginated query. :param items: The models returned by the query - :type items: List[MODEL] + :type items: list[MODEL] :param page_info: The pagination metadata :type page_info: PageInfo """ - items: List[MODEL] + items: list[MODEL] page_info: PageInfo @@ -116,18 +116,18 @@ class CursorPageInfo(BaseModel): :type has_previous_page: bool :param start_cursor: The cursor pointing to the first item in the page, if at least one item is returned. - :type start_cursor: Union[CursorReference, None] + :type start_cursor: CursorReference | None :param end_cursor: The cursor pointing to the last item in the page, if at least one item is returned. - :type end_cursor: Union[CursorReference, None] + :type end_cursor: CursorReference | None """ items_per_page: int total_items: int has_next_page: bool = False has_previous_page: bool = False - start_cursor: Union[CursorReference, None] = None - end_cursor: Union[CursorReference, None] = None + start_cursor: CursorReference | None = None + end_cursor: CursorReference | None = None class CursorPaginatedResult(BaseModel, Generic[MODEL]): @@ -135,10 +135,10 @@ class CursorPaginatedResult(BaseModel, Generic[MODEL]): The result of a cursor paginated query. :param items: The models returned by the query - :type items: List[MODEL] + :type items: list[MODEL] :param page_info: The pagination metadata :type page_info: CursorPageInfo """ - items: List[MODEL] + items: list[MODEL] page_info: CursorPageInfo diff --git a/sqlalchemy_bind_manager/_repository/result_presenters.py b/sqlalchemy_bind_manager/_repository/result_presenters.py index dee9e47..d457982 100644 --- a/sqlalchemy_bind_manager/_repository/result_presenters.py +++ b/sqlalchemy_bind_manager/_repository/result_presenters.py @@ -19,7 +19,6 @@ # DEALINGS IN THE SOFTWARE. from math import ceil -from typing import List, Union from .common import ( CURSOR_VALUE, @@ -37,10 +36,10 @@ class CursorPaginatedResultPresenter: @classmethod def build_result( cls, - result_items: List[MODEL], + result_items: list[MODEL], total_items_count: int, items_per_page: int, - cursor_reference: Union[CursorReference, None], + cursor_reference: CursorReference | None, is_before_cursor: bool, ) -> CursorPaginatedResult: """ @@ -86,7 +85,7 @@ def _build_empty_items_result( @staticmethod def _build_no_cursor_result( - result_items: List[MODEL], + result_items: list[MODEL], total_items_count: int, items_per_page: int, ) -> CursorPaginatedResult: @@ -115,7 +114,7 @@ def _build_no_cursor_result( @staticmethod def _build_before_cursor_result( - result_items: List[MODEL], + result_items: list[MODEL], total_items_count: int, items_per_page: int, cursor_reference: CursorReference[CURSOR_VALUE], @@ -164,7 +163,7 @@ def _build_before_cursor_result( @staticmethod def _build_after_cursor_result( - result_items: List[MODEL], + result_items: list[MODEL], total_items_count: int, items_per_page: int, cursor_reference: CursorReference[CURSOR_VALUE], @@ -215,7 +214,7 @@ def _build_after_cursor_result( class PaginatedResultPresenter: @staticmethod def build_result( - result_items: List[MODEL], + result_items: list[MODEL], total_items_count: int, page: int, items_per_page: int, diff --git a/sqlalchemy_bind_manager/_repository/sync.py b/sqlalchemy_bind_manager/_repository/sync.py index 0cc3398..4e6d6d8 100644 --- a/sqlalchemy_bind_manager/_repository/sync.py +++ b/sqlalchemy_bind_manager/_repository/sync.py @@ -18,18 +18,12 @@ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # DEALINGS IN THE SOFTWARE. +from collections.abc import Iterable, Iterator, Mapping from contextlib import contextmanager from typing import ( Any, Generic, - Iterable, - Iterator, - List, Literal, - Mapping, - Tuple, - Type, - Union, ) from sqlalchemy import select @@ -56,13 +50,13 @@ class SQLAlchemyRepository( BaseRepository[MODEL], ): _session_handler: SessionHandler - _external_session: Union[Session, None] + _external_session: Session | None def __init__( self, - bind: Union[SQLAlchemyBind, None] = None, - session: Union[Session, None] = None, - model_class: Union[Type[MODEL], None] = None, + bind: SQLAlchemyBind | None = None, + session: Session | None = None, + model_class: type[MODEL] | None = None, ) -> None: super().__init__(model_class=model_class) if not (bool(bind) ^ bool(session)): @@ -86,7 +80,7 @@ def get(self, identifier: PRIMARY_KEY) -> MODEL: raise ModelNotFoundError("No rows found for provided primary key.") return model - def get_many(self, identifiers: Iterable[PRIMARY_KEY]) -> List[MODEL]: + def get_many(self, identifiers: Iterable[PRIMARY_KEY]) -> list[MODEL]: """Get a list of models by primary keys. :param identifiers: A list of primary keys @@ -142,11 +136,9 @@ def delete_many(self, instances: Iterable[MODEL]) -> None: def find( self, - search_params: Union[Mapping[str, Any], None] = None, - order_by: Union[ - Iterable[Union[str, Tuple[str, Literal["asc", "desc"]]]], None - ] = None, - ) -> List[MODEL]: + search_params: Mapping[str, Any] | None = None, + order_by: Iterable[str | tuple[str, Literal["asc", "desc"]]] | None = None, + ) -> list[MODEL]: """Find models using filters. E.g. @@ -174,10 +166,8 @@ def paginated_find( self, items_per_page: int, page: int = 1, - search_params: Union[Mapping[str, Any], None] = None, - order_by: Union[ - Iterable[Union[str, Tuple[str, Literal["asc", "desc"]]]], None - ] = None, + search_params: Mapping[str, Any] | None = None, + order_by: Iterable[str | tuple[str, Literal["asc", "desc"]]] | None = None, ) -> PaginatedResult[MODEL]: """Find models using filters and limit/offset pagination. Returned results do include pagination metadata. @@ -224,9 +214,9 @@ def paginated_find( def cursor_paginated_find( self, items_per_page: int, - cursor_reference: Union[CursorReference, None] = None, + cursor_reference: CursorReference | None = None, is_before_cursor: bool = False, - search_params: Union[Mapping[str, Any], None] = None, + search_params: Mapping[str, Any] | None = None, ) -> CursorPaginatedResult[MODEL]: """Find models using filters and cursor based pagination. Returned results do include pagination metadata. diff --git a/sqlalchemy_bind_manager/_session_handler.py b/sqlalchemy_bind_manager/_session_handler.py index 35989b5..dea25bc 100644 --- a/sqlalchemy_bind_manager/_session_handler.py +++ b/sqlalchemy_bind_manager/_session_handler.py @@ -20,8 +20,8 @@ import asyncio import logging +from collections.abc import AsyncIterator, Iterator from contextlib import asynccontextmanager, contextmanager -from typing import AsyncIterator, Iterator from sqlalchemy.ext.asyncio import ( AsyncSession, diff --git a/sqlalchemy_bind_manager/_unit_of_work/__init__.py b/sqlalchemy_bind_manager/_unit_of_work/__init__.py index defadf2..b4b2e6e 100644 --- a/sqlalchemy_bind_manager/_unit_of_work/__init__.py +++ b/sqlalchemy_bind_manager/_unit_of_work/__init__.py @@ -19,8 +19,9 @@ # DEALINGS IN THE SOFTWARE. from abc import ABC +from collections.abc import AsyncIterator, Iterator from contextlib import asynccontextmanager, contextmanager -from typing import AsyncIterator, Dict, Generic, Iterator, Type, TypeVar, Union +from typing import Generic, TypeVar from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.orm import Session @@ -42,7 +43,7 @@ class BaseUnitOfWork(Generic[REPOSITORY, SESSION_HANDLER], ABC): _session_handler: SESSION_HANDLER - _repositories: Dict[str, REPOSITORY] + _repositories: dict[str, REPOSITORY] def __init__(self): self._repositories = {} @@ -50,8 +51,8 @@ def __init__(self): def register_repository( self, name: str, - repository_class: Type[REPOSITORY], - model_class: Union[Type, None] = None, + repository_class: type[REPOSITORY], + model_class: type | None = None, *args, **kwargs, ): diff --git a/tests/conftest.py b/tests/conftest.py index f84e1b1..80f2373 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,6 +1,6 @@ import inspect from contextlib import _AsyncGeneratorContextManager, asynccontextmanager -from typing import ClassVar, Tuple, Type, Union +from typing import ClassVar from uuid import uuid4 import pytest @@ -106,7 +106,7 @@ def sa_bind(request, sa_manager): @pytest.fixture -async def model_classes(sa_bind) -> Tuple[Type, Type]: +async def model_classes(sa_bind) -> tuple[type, type]: class ParentModel(sa_bind.declarative_base): __tablename__ = "parent_model" # required in order to access columns with server defaults @@ -149,7 +149,7 @@ class ChildModel(sa_bind.declarative_base): @pytest.fixture -async def model_class(model_classes: Tuple[Type, Type]) -> Type: +async def model_class(model_classes: tuple[type, type]) -> type: return model_classes[0] @@ -164,8 +164,8 @@ def session_handler_class(sa_bind): @pytest.fixture def repository_class( - sa_bind: Union[SQLAlchemyBind, SQLAlchemyAsyncBind], -) -> Type[Union[SQLAlchemyAsyncRepository, SQLAlchemyRepository]]: + sa_bind: SQLAlchemyBind | SQLAlchemyAsyncBind, +) -> type[SQLAlchemyAsyncRepository | SQLAlchemyRepository]: base_class = ( SQLAlchemyRepository if isinstance(sa_bind, SQLAlchemyBind) diff --git a/tests/repository/test_composite_pk.py b/tests/repository/test_composite_pk.py index ca87d1e..ccf2d3f 100644 --- a/tests/repository/test_composite_pk.py +++ b/tests/repository/test_composite_pk.py @@ -1,4 +1,4 @@ -from typing import ClassVar, Type +from typing import ClassVar import pytest from sqlalchemy import Column, Integer, String @@ -23,7 +23,7 @@ def sa_manager() -> SQLAlchemyBindManager: @pytest.fixture -def model_class_composite_pk(sa_manager) -> Type: +def model_class_composite_pk(sa_manager) -> type: default_bind = sa_manager.get_bind() class MyModel(default_bind.declarative_base): @@ -43,7 +43,7 @@ class MyModel(default_bind.declarative_base): @pytest.fixture -def repository_class(model_class_composite_pk) -> Type[SQLAlchemyRepository]: +def repository_class(model_class_composite_pk) -> type[SQLAlchemyRepository]: class MyRepository(SQLAlchemyRepository[model_class_composite_pk]): _model = model_class_composite_pk