Skip to content

Commit

Permalink
fix: typing hint adjustment for service.typing (#282)
Browse files Browse the repository at this point in the history
* fix: typing hint adjustment for `service.typing`

* fix: revert `Sequence` change for 3.8 support

* feat: updated typing

* chore: bump version

* feat: updated type hints

* fix: ignore

* feat: update

* feat: split typing from type guards

* fix: linting and docs

* fix: remove usused ignores

* feat: more linting updates

* fix: maybe this?

* fix: exclude for now
  • Loading branch information
cofin authored Nov 7, 2024
1 parent 328bad0 commit 4f2a345
Show file tree
Hide file tree
Showing 19 changed files with 360 additions and 269 deletions.
4 changes: 1 addition & 3 deletions advanced_alchemy/config/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@

from __future__ import annotations

from typing import TYPE_CHECKING, Any, Callable, Literal, Tuple
from typing import TYPE_CHECKING, Any, Callable, Literal, Mapping, Sequence, Tuple

if TYPE_CHECKING:
from collections.abc import Mapping, Sequence

from typing_extensions import TypeAlias


Expand Down
3 changes: 1 addition & 2 deletions advanced_alchemy/extensions/litestar/alembic.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
from __future__ import annotations

from collections.abc import Sequence
from contextlib import suppress
from typing import TYPE_CHECKING
from typing import TYPE_CHECKING, Sequence

from advanced_alchemy.alembic.commands import AlembicCommands as _AlembicCommands

Expand Down
3 changes: 1 addition & 2 deletions advanced_alchemy/extensions/litestar/plugins/init/plugin.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
from __future__ import annotations

import contextlib
from collections.abc import Sequence
from typing import TYPE_CHECKING, Any, cast
from typing import TYPE_CHECKING, Any, Sequence, cast

from litestar.di import Provide
from litestar.dto import DTOData
Expand Down
4 changes: 2 additions & 2 deletions advanced_alchemy/repository/_async.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@
TYPE_CHECKING,
Any,
Final,
Iterable,
List,
Literal,
Optional,
Protocol,
Sequence,
Tuple,
cast,
runtime_checkable,
Expand Down Expand Up @@ -46,8 +48,6 @@
from advanced_alchemy.utils.text import slugify

if TYPE_CHECKING:
from collections.abc import Iterable, Sequence

from sqlalchemy.engine.interfaces import _CoreSingleExecuteParams # pyright: ignore[reportPrivateUsage]
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.ext.asyncio.scoping import async_scoped_session
Expand Down
4 changes: 2 additions & 2 deletions advanced_alchemy/repository/_sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@
TYPE_CHECKING,
Any,
Final,
Iterable,
List,
Literal,
Optional,
Protocol,
Sequence,
Tuple,
cast,
runtime_checkable,
Expand Down Expand Up @@ -48,8 +50,6 @@
from advanced_alchemy.utils.text import slugify

if TYPE_CHECKING:
from collections.abc import Iterable, Sequence

from sqlalchemy.engine.interfaces import _CoreSingleExecuteParams # pyright: ignore[reportPrivateUsage]
from sqlalchemy.orm.scoping import scoped_session
from sqlalchemy.orm.strategy_options import _AbstractLoad # pyright: ignore[reportPrivateUsage]
Expand Down
10 changes: 1 addition & 9 deletions advanced_alchemy/repository/_util.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,6 @@
from __future__ import annotations

from collections.abc import Iterable, Sequence
from typing import (
TYPE_CHECKING,
Any,
Literal,
Protocol,
Union,
cast,
)
from typing import TYPE_CHECKING, Any, Iterable, Literal, Protocol, Sequence, Union, cast

from sqlalchemy.orm import InstrumentedAttribute, MapperProperty, RelationshipProperty, joinedload, selectinload
from sqlalchemy.orm.strategy_options import (
Expand Down
4 changes: 1 addition & 3 deletions advanced_alchemy/service/_async.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from __future__ import annotations

from contextlib import asynccontextmanager
from typing import TYPE_CHECKING, Any, Generic, List, cast
from typing import TYPE_CHECKING, Any, AsyncIterator, Generic, Iterable, List, Sequence, cast

from sqlalchemy import Select
from typing_extensions import Self
Expand Down Expand Up @@ -36,8 +36,6 @@
from advanced_alchemy.utils.dataclass import Empty, EmptyType

if TYPE_CHECKING:
from collections.abc import AsyncIterator, Iterable, Sequence

from sqlalchemy import Select, StatementLambdaElement
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.ext.asyncio.scoping import async_scoped_session
Expand Down
4 changes: 1 addition & 3 deletions advanced_alchemy/service/_sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from __future__ import annotations

from contextlib import contextmanager
from typing import TYPE_CHECKING, Any, Generic, List, cast
from typing import TYPE_CHECKING, Any, Generic, Iterable, Iterator, List, Sequence, cast

from sqlalchemy import Select
from typing_extensions import Self
Expand Down Expand Up @@ -38,8 +38,6 @@
from advanced_alchemy.utils.dataclass import Empty, EmptyType

if TYPE_CHECKING:
from collections.abc import Iterable, Iterator, Sequence

from sqlalchemy import Select, StatementLambdaElement
from sqlalchemy.orm import InstrumentedAttribute, Session
from sqlalchemy.orm.scoping import scoped_session
Expand Down
119 changes: 119 additions & 0 deletions advanced_alchemy/service/_typing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
"""This is a simple wrapper around a few important classes in each library.
This is used to ensure compatibility when one or more of the libraries are installed.
"""

from __future__ import annotations

from importlib.util import find_spec
from typing import (
Any,
ClassVar,
Generic,
Protocol,
cast,
runtime_checkable,
)

from typing_extensions import TypeVar, dataclass_transform

PYDANTIC_INSTALLED = bool(find_spec("pydantic"))
MSGSPEC_INSTALLED = bool(find_spec("msgspec"))
LITESTAR_INSTALLED = bool(find_spec("litestar"))

T = TypeVar("T")

if not PYDANTIC_INSTALLED:

@runtime_checkable
class BaseModel(Protocol):
"""Placeholder Implementation"""

model_fields: ClassVar[dict[str, Any]]

def model_dump(*args: Any, **kwargs: Any) -> dict[str, Any]:
"""Placeholder"""
return {}

class TypeAdapter(Generic[T]):
"""Placeholder Implementation"""

def __init__(self, *args: Any, **kwargs: Any) -> None:
"""Init"""

def validate_python(self, data: Any, *args: Any, **kwargs: Any) -> T:
"""Stub"""
return cast("T", data)

class FailFast: # pyright: ignore[reportRedeclaration]
"""Placeholder Implementation for FailFast"""

def __init__(self, *args: Any, **kwargs: Any) -> None:
"""Init"""

def __call__(self, *args: Any, **kwargs: Any) -> None:
"""Placeholder"""


else:
from pydantic import BaseModel, FailFast, TypeAdapter # type: ignore[assignment]


if not MSGSPEC_INSTALLED:
import enum

@dataclass_transform()
@runtime_checkable
class Struct(Protocol):
"""Placeholder Implementation"""

__struct_fields__: ClassVar[tuple[str, ...]]

def convert(*args: Any, **kwargs: Any) -> Any: # noqa: ARG001
"""Placeholder implementation"""
return {}

class UnsetType(enum.Enum):
UNSET = "UNSET"

UNSET = UnsetType.UNSET # pyright: ignore[reportConstantRedefinition]
else:
from msgspec import ( # type: ignore[assignment]
UNSET, # pyright: ignore[reportConstantRedefinition]
Struct,
UnsetType, # pyright: ignore[reportAssignmentType]
convert,
)

if not LITESTAR_INSTALLED:

class DTOData(Generic[T]):
"""Placeholder implementation"""

def create_instance(*args: Any, **kwargs: Any) -> T:
"""Placeholder implementation"""
return cast("T", kwargs)

def update_instance(self, instance: T, **kwargs: Any) -> T:
"""Placeholder implementation"""
return cast("T", kwargs)

def as_builtins(self) -> Any:
"""Placeholder implementation"""
return {}
else:
from litestar.dto.data_structures import DTOData # type: ignore[assignment]


__all__ = (
"PYDANTIC_INSTALLED",
"MSGSPEC_INSTALLED",
"LITESTAR_INSTALLED",
"DTOData",
"BaseModel",
"TypeAdapter",
"FailFast",
"Struct",
"convert",
"UNSET",
)
13 changes: 6 additions & 7 deletions advanced_alchemy/service/_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@

from __future__ import annotations

from collections.abc import Callable, Sequence
from functools import partial
from pathlib import Path, PurePath
from typing import TYPE_CHECKING, Any, List, cast, overload
from typing import TYPE_CHECKING, Any, Callable, List, Sequence, cast, overload
from uuid import UUID

from advanced_alchemy.exceptions import AdvancedAlchemyError
Expand All @@ -19,10 +18,10 @@
from advanced_alchemy.service.typing import (
MSGSPEC_INSTALLED,
PYDANTIC_INSTALLED,
BaseModel, # pyright: ignore[reportAttributeAccessIssue]
BaseModel,
ModelDTOT,
Struct, # pyright: ignore[reportAttributeAccessIssue]
convert, # pyright: ignore[reportAttributeAccessIssue]
Struct,
convert,
get_type_adapter,
)

Expand Down Expand Up @@ -168,7 +167,7 @@ def to_schema(
offset=limit_offset.offset,
total=total,
)
if MSGSPEC_INSTALLED and issubclass(schema_type, Struct):
if MSGSPEC_INSTALLED and issubclass(schema_type, Struct): # type: ignore[misc] # pyright: ignore[reportGeneralTypeIssues]
if not isinstance(data, Sequence):
return cast(
"ModelDTOT",
Expand Down Expand Up @@ -204,7 +203,7 @@ def to_schema(
total=total,
)

if PYDANTIC_INSTALLED and issubclass(schema_type, BaseModel):
if PYDANTIC_INSTALLED and issubclass(schema_type, BaseModel): # type: ignore[misc] # pyright: ignore[reportGeneralTypeIssues]
if not isinstance(data, Sequence):
return cast(
"ModelDTOT",
Expand Down
7 changes: 1 addition & 6 deletions advanced_alchemy/service/pagination.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
from __future__ import annotations

from collections.abc import Sequence # noqa: TCH003
from dataclasses import dataclass
from typing import Generic
from uuid import UUID

from typing_extensions import TypeVar
from typing import Generic, Sequence, TypeVar

T = TypeVar("T")
C = TypeVar("C", int, str, UUID)

__all__ = ("OffsetPagination",)

Expand Down
Loading

0 comments on commit 4f2a345

Please sign in to comment.