Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!: remove deprecated packages removed in v1.0.0 #419

Merged
merged 3 commits into from
Mar 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 16 additions & 81 deletions advanced_alchemy/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,74 +23,45 @@
from typing_extensions import Self, TypeVar

from advanced_alchemy.mixins import (
AuditColumns as _AuditColumns,
)
from advanced_alchemy.mixins import (
BigIntPrimaryKey as _BigIntPrimaryKey,
)
from advanced_alchemy.mixins import (
NanoIDPrimaryKey as _NanoIDPrimaryKey,
)
from advanced_alchemy.mixins import (
UUIDPrimaryKey as _UUIDPrimaryKey,
)
from advanced_alchemy.mixins import (
UUIDv6PrimaryKey as _UUIDv6PrimaryKey,
)
from advanced_alchemy.mixins import (
UUIDv7PrimaryKey as _UUIDv7PrimaryKey,
AuditColumns,
BigIntPrimaryKey,
NanoIDPrimaryKey,
UUIDPrimaryKey,
UUIDv6PrimaryKey,
UUIDv7PrimaryKey,
)
from advanced_alchemy.types import GUID, DateTimeUTC, JsonB
from advanced_alchemy.utils.dataclass import DataclassProtocol
from advanced_alchemy.utils.deprecation import warn_deprecation

if TYPE_CHECKING:
# these should stay here since they are deprecated. They are imported in the __getattr__ function
from sqlalchemy.sql import FromClause
from sqlalchemy.sql.schema import (
_NamingSchemaParameter as NamingSchemaParameter, # pyright: ignore[reportPrivateUsage]
)

from advanced_alchemy.mixins import (
AuditColumns,
BigIntPrimaryKey,
NanoIDPrimaryKey,
SlugKey,
UUIDPrimaryKey,
UUIDv6PrimaryKey,
UUIDv7PrimaryKey,
)


__all__ = (
"AdvancedDeclarativeBase",
"AuditColumns",
"BasicAttributes",
"BigIntAuditBase",
"BigIntBase",
"BigIntBaseT",
"BigIntPrimaryKey",
"CommonTableAttributes",
"ModelProtocol",
"NanoIDAuditBase",
"NanoIDBase",
"NanoIDBaseT",
"NanoIDPrimaryKey",
"SQLQuery",
"SlugKey",
"TableArgsType",
"UUIDAuditBase",
"UUIDBase",
"UUIDBaseT",
"UUIDPrimaryKey",
"UUIDv6AuditBase",
"UUIDv6Base",
"UUIDv6BaseT",
"UUIDv6PrimaryKey",
"UUIDv7AuditBase",
"UUIDv7Base",
"UUIDv7BaseT",
"UUIDv7PrimaryKey",
"convention",
"create_registry",
"merge_table_arguments",
Expand All @@ -100,42 +71,6 @@
)


def __getattr__(attr_name: str) -> object:
if attr_name == "__path__":
return __file__

_deprecated_attrs = {
"SlugKey",
"AuditColumns",
"NanoIDPrimaryKey",
"BigIntPrimaryKey",
"UUIDPrimaryKey",
"UUIDv6PrimaryKey",
"UUIDv7PrimaryKey",
}
if attr_name in _deprecated_attrs:
from advanced_alchemy import mixins

module = "advanced_alchemy.mixins"
value = globals()[attr_name] = getattr(mixins, attr_name)

warn_deprecation(
deprecated_name=f"advanced_alchemy.base.{attr_name}",
version="0.26.0",
kind="import",
removal_in="1.0.0",
info=f"importing {attr_name} from 'advanced_alchemy.base' is deprecated, please import it from '{module}' instead",
)

return value
if attr_name in set(__all__).difference(_deprecated_attrs):
value = globals()[attr_name] = locals()[attr_name]
return value

msg = f"module {__name__!r} has no attribute {attr_name!r}"
raise AttributeError(msg)


UUIDBaseT = TypeVar("UUIDBaseT", bound="UUIDBase")
"""Type variable for :class:`UUIDBase`."""
BigIntBaseT = TypeVar("BigIntBaseT", bound="BigIntBase")
Expand Down Expand Up @@ -385,7 +320,7 @@ def __init_subclass__(cls, **kwargs: Any) -> None:
super().__init_subclass__(**kwargs)


class UUIDBase(_UUIDPrimaryKey, CommonTableAttributes, AdvancedDeclarativeBase, AsyncAttrs):
class UUIDBase(UUIDPrimaryKey, CommonTableAttributes, AdvancedDeclarativeBase, AsyncAttrs):
"""Base for all SQLAlchemy declarative models with UUID v4 primary keys.

.. seealso::
Expand All @@ -398,7 +333,7 @@ class UUIDBase(_UUIDPrimaryKey, CommonTableAttributes, AdvancedDeclarativeBase,
__abstract__ = True


class UUIDAuditBase(CommonTableAttributes, _UUIDPrimaryKey, _AuditColumns, AdvancedDeclarativeBase, AsyncAttrs):
class UUIDAuditBase(CommonTableAttributes, UUIDPrimaryKey, AuditColumns, AdvancedDeclarativeBase, AsyncAttrs):
"""Base for declarative models with UUID v4 primary keys and audit columns.

.. seealso::
Expand All @@ -412,7 +347,7 @@ class UUIDAuditBase(CommonTableAttributes, _UUIDPrimaryKey, _AuditColumns, Advan
__abstract__ = True


class UUIDv6Base(_UUIDv6PrimaryKey, CommonTableAttributes, AdvancedDeclarativeBase, AsyncAttrs):
class UUIDv6Base(UUIDv6PrimaryKey, CommonTableAttributes, AdvancedDeclarativeBase, AsyncAttrs):
"""Base for all SQLAlchemy declarative models with UUID v6 primary keys.

.. seealso::
Expand All @@ -425,7 +360,7 @@ class UUIDv6Base(_UUIDv6PrimaryKey, CommonTableAttributes, AdvancedDeclarativeBa
__abstract__ = True


class UUIDv6AuditBase(CommonTableAttributes, _UUIDv6PrimaryKey, _AuditColumns, AdvancedDeclarativeBase, AsyncAttrs):
class UUIDv6AuditBase(CommonTableAttributes, UUIDv6PrimaryKey, AuditColumns, AdvancedDeclarativeBase, AsyncAttrs):
"""Base for declarative models with UUID v6 primary keys and audit columns.

.. seealso::
Expand All @@ -439,7 +374,7 @@ class UUIDv6AuditBase(CommonTableAttributes, _UUIDv6PrimaryKey, _AuditColumns, A
__abstract__ = True


class UUIDv7Base(_UUIDv7PrimaryKey, CommonTableAttributes, AdvancedDeclarativeBase, AsyncAttrs):
class UUIDv7Base(UUIDv7PrimaryKey, CommonTableAttributes, AdvancedDeclarativeBase, AsyncAttrs):
"""Base for all SQLAlchemy declarative models with UUID v7 primary keys.

.. seealso::
Expand All @@ -452,7 +387,7 @@ class UUIDv7Base(_UUIDv7PrimaryKey, CommonTableAttributes, AdvancedDeclarativeBa
__abstract__ = True


class UUIDv7AuditBase(CommonTableAttributes, _UUIDv7PrimaryKey, _AuditColumns, AdvancedDeclarativeBase, AsyncAttrs):
class UUIDv7AuditBase(CommonTableAttributes, UUIDv7PrimaryKey, AuditColumns, AdvancedDeclarativeBase, AsyncAttrs):
"""Base for declarative models with UUID v7 primary keys and audit columns.

.. seealso::
Expand All @@ -466,7 +401,7 @@ class UUIDv7AuditBase(CommonTableAttributes, _UUIDv7PrimaryKey, _AuditColumns, A
__abstract__ = True


class NanoIDBase(_NanoIDPrimaryKey, CommonTableAttributes, AdvancedDeclarativeBase, AsyncAttrs):
class NanoIDBase(NanoIDPrimaryKey, CommonTableAttributes, AdvancedDeclarativeBase, AsyncAttrs):
"""Base for all SQLAlchemy declarative models with Nano ID primary keys.

.. seealso::
Expand All @@ -479,7 +414,7 @@ class NanoIDBase(_NanoIDPrimaryKey, CommonTableAttributes, AdvancedDeclarativeBa
__abstract__ = True


class NanoIDAuditBase(CommonTableAttributes, _NanoIDPrimaryKey, _AuditColumns, AdvancedDeclarativeBase, AsyncAttrs):
class NanoIDAuditBase(CommonTableAttributes, NanoIDPrimaryKey, AuditColumns, AdvancedDeclarativeBase, AsyncAttrs):
"""Base for declarative models with Nano ID primary keys and audit columns.

.. seealso::
Expand All @@ -493,7 +428,7 @@ class NanoIDAuditBase(CommonTableAttributes, _NanoIDPrimaryKey, _AuditColumns, A
__abstract__ = True


class BigIntBase(_BigIntPrimaryKey, CommonTableAttributes, AdvancedDeclarativeBase, AsyncAttrs):
class BigIntBase(BigIntPrimaryKey, CommonTableAttributes, AdvancedDeclarativeBase, AsyncAttrs):
"""Base for all SQLAlchemy declarative models with BigInt primary keys.

.. seealso::
Expand All @@ -506,7 +441,7 @@ class BigIntBase(_BigIntPrimaryKey, CommonTableAttributes, AdvancedDeclarativeBa
__abstract__ = True


class BigIntAuditBase(CommonTableAttributes, _BigIntPrimaryKey, _AuditColumns, AdvancedDeclarativeBase, AsyncAttrs):
class BigIntAuditBase(CommonTableAttributes, BigIntPrimaryKey, AuditColumns, AdvancedDeclarativeBase, AsyncAttrs):
"""Base for declarative models with BigInt primary keys and audit columns.

.. seealso::
Expand Down
25 changes: 0 additions & 25 deletions advanced_alchemy/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,8 @@
from sqlalchemy.exc import InvalidRequestError as SQLAlchemyInvalidRequestError
from sqlalchemy.exc import MultipleResultsFound, SQLAlchemyError, StatementError

from advanced_alchemy.utils.deprecation import deprecated

__all__ = (
"AdvancedAlchemyError",
"ConflictError",
"DuplicateKeyError",
"ErrorMessages",
"ForeignKeyError",
Expand Down Expand Up @@ -173,28 +170,6 @@ class RepositoryError(AdvancedAlchemyError):
"""


class ConflictError(RepositoryError):
"""Data integrity error.

Args:
*args: Variable length argument list passed to parent class.
detail: Detailed error message.

Note:
This class is deprecated in favor of :class:`advanced_alchemy.exceptions.IntegrityError`.
"""

@deprecated(
version="0.7.1",
alternative="advanced_alchemy.exceptions.IntegrityError",
kind="method",
removal_in="1.0.0",
info="`ConflictError` has been renamed to `IntegrityError`",
)
def __init__(self, *args: Any, detail: str = "") -> None:
super().__init__(*args, detail=detail)


class IntegrityError(RepositoryError):
"""Data integrity error.

Expand Down
4 changes: 2 additions & 2 deletions advanced_alchemy/utils/deprecation.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ def deprecated(
"""Create a decorator wrapping a function, method or property with a warning call about a (pending) deprecation.

Args:
version: Litestar version where the deprecation will occur
removal_in: Litestar version where the deprecated function will be removed
version: Advanced Alchemy version where the deprecation will occur
removal_in: Advanced Alchemy version where the deprecated function will be removed
alternative: Name of a function that should be used instead
info: Additional information
pending: Use :class:`warnings.PendingDeprecationWarning` instead of :class:`warnings.DeprecationWarning`
Expand Down
53 changes: 8 additions & 45 deletions tests/unit/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,54 +4,11 @@

import warnings

import pytest

from tests.helpers import purge_module


def test_deprecated_uuid_primary_keys() -> None:
"""Test that using UUIDv7PrimaryKey from base raises a deprecation warning."""
purge_module(["advanced_alchemy.base"], __file__)
with pytest.warns(DeprecationWarning, match="please import it from 'advanced_alchemy.mixins' instead"):
from advanced_alchemy.base import UUIDv7PrimaryKey

with pytest.warns(DeprecationWarning, match="please import it from 'advanced_alchemy.mixins' instead"):
from advanced_alchemy.base import UUIDv6PrimaryKey

with pytest.warns(DeprecationWarning, match="please import it from 'advanced_alchemy.mixins' instead"):
from advanced_alchemy.base import UUIDPrimaryKey


def test_deprecated_slug_mixin() -> None:
"""Test that using SlugMixin from base raises a deprecation warning."""
purge_module(["advanced_alchemy.base", "advanced_alchemy.mixins.slug", "advanced_alchemy.mixins"], __file__)
with pytest.warns(DeprecationWarning, match="please import it from 'advanced_alchemy.mixins' instead"):
from advanced_alchemy.base import SlugKey


def test_deprecated_bigint_primary_key() -> None:
"""Test that using BigIntPrimaryKey from base raises a deprecation warning."""
purge_module(["advanced_alchemy.base", "advanced_alchemy.mixins.bigint", "advanced_alchemy.mixins"], __file__)
with pytest.warns(DeprecationWarning, match="please import it from 'advanced_alchemy.mixins' instead"):
from advanced_alchemy.base import BigIntPrimaryKey


def test_deprecated_nanoid_primary_key() -> None:
"""Test that using NanoIDPrimaryKey from base raises a deprecation warning."""
purge_module(["advanced_alchemy.base", "advanced_alchemy.mixins.nanoid", "advanced_alchemy.mixins"], __file__)
with pytest.warns(DeprecationWarning, match="please import it from 'advanced_alchemy.mixins' instead"):
from advanced_alchemy.base import NanoIDPrimaryKey


def test_deprecated_audit_columns() -> None:
"""Test that using AuditColumns from base raises a deprecation warning."""
purge_module(["advanced_alchemy.base", "advanced_alchemy.mixins.audit", "advanced_alchemy.mixins"], __file__)
with pytest.warns(DeprecationWarning, match="please import it from 'advanced_alchemy.mixins' instead"):
from advanced_alchemy.base import AuditColumns


def test_deprecated_classes_functionality() -> None:
"""Test that deprecated classes maintain functionality while warning."""
"""Test that mixins classes maintain have base functionality."""
purge_module(["advanced_alchemy.base", "advanced_alchemy.mixins"], __file__)

warnings.filterwarnings("ignore", category=DeprecationWarning)
Expand All @@ -60,7 +17,13 @@ def test_deprecated_classes_functionality() -> None:
warnings.filterwarnings("ignore", category=sa_exc.SAWarning)

# Test instantiation and basic attributes
from advanced_alchemy.base import AuditColumns, NanoIDPrimaryKey, UUIDPrimaryKey, UUIDv6PrimaryKey, UUIDv7PrimaryKey
from advanced_alchemy.mixins import (
AuditColumns,
NanoIDPrimaryKey,
UUIDPrimaryKey,
UUIDv6PrimaryKey,
UUIDv7PrimaryKey,
)

uuidv7_pk = UUIDv7PrimaryKey()
uuidv6_pk = UUIDv6PrimaryKey()
Expand Down
10 changes: 0 additions & 10 deletions tests/unit/test_exceptions.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import contextlib

import pytest
from sqlalchemy.exc import (
IntegrityError as SQLAlchemyIntegrityError,
Expand All @@ -24,14 +22,6 @@
)


async def test_repo_get_or_create_deprecation() -> None:
with pytest.warns(DeprecationWarning):
from advanced_alchemy.exceptions import ConflictError

with contextlib.suppress(Exception):
raise ConflictError


def test_wrap_sqlalchemy_exception_multiple_results_found() -> None:
with pytest.raises(MultipleResultsFoundError), wrap_sqlalchemy_exception():
raise MultipleResultsFound()
Expand Down
6 changes: 3 additions & 3 deletions uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.