about summary refs log tree commit diff
path: root/.venv/lib/python3.12/site-packages/sqlalchemy/orm/decl_api.py
diff options
context:
space:
mode:
Diffstat (limited to '.venv/lib/python3.12/site-packages/sqlalchemy/orm/decl_api.py')
-rw-r--r--.venv/lib/python3.12/site-packages/sqlalchemy/orm/decl_api.py1917
1 files changed, 1917 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/sqlalchemy/orm/decl_api.py b/.venv/lib/python3.12/site-packages/sqlalchemy/orm/decl_api.py
new file mode 100644
index 00000000..c32851de
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/sqlalchemy/orm/decl_api.py
@@ -0,0 +1,1917 @@
+# orm/decl_api.py
+# Copyright (C) 2005-2025 the SQLAlchemy authors and contributors
+# <see AUTHORS file>
+#
+# This module is part of SQLAlchemy and is released under
+# the MIT License: https://www.opensource.org/licenses/mit-license.php
+
+"""Public API functions and helpers for declarative."""
+
+from __future__ import annotations
+
+import itertools
+import re
+import typing
+from typing import Any
+from typing import Callable
+from typing import ClassVar
+from typing import Dict
+from typing import FrozenSet
+from typing import Generic
+from typing import Iterable
+from typing import Iterator
+from typing import Mapping
+from typing import Optional
+from typing import overload
+from typing import Set
+from typing import Tuple
+from typing import Type
+from typing import TYPE_CHECKING
+from typing import TypeVar
+from typing import Union
+import weakref
+
+from . import attributes
+from . import clsregistry
+from . import instrumentation
+from . import interfaces
+from . import mapperlib
+from ._orm_constructors import composite
+from ._orm_constructors import deferred
+from ._orm_constructors import mapped_column
+from ._orm_constructors import relationship
+from ._orm_constructors import synonym
+from .attributes import InstrumentedAttribute
+from .base import _inspect_mapped_class
+from .base import _is_mapped_class
+from .base import Mapped
+from .base import ORMDescriptor
+from .decl_base import _add_attribute
+from .decl_base import _as_declarative
+from .decl_base import _ClassScanMapperConfig
+from .decl_base import _declarative_constructor
+from .decl_base import _DeferredMapperConfig
+from .decl_base import _del_attribute
+from .decl_base import _mapper
+from .descriptor_props import Composite
+from .descriptor_props import Synonym
+from .descriptor_props import Synonym as _orm_synonym
+from .mapper import Mapper
+from .properties import MappedColumn
+from .relationships import RelationshipProperty
+from .state import InstanceState
+from .. import exc
+from .. import inspection
+from .. import util
+from ..sql import sqltypes
+from ..sql.base import _NoArg
+from ..sql.elements import SQLCoreOperations
+from ..sql.schema import MetaData
+from ..sql.selectable import FromClause
+from ..util import hybridmethod
+from ..util import hybridproperty
+from ..util import typing as compat_typing
+from ..util import warn_deprecated
+from ..util.typing import CallableReference
+from ..util.typing import de_optionalize_union_types
+from ..util.typing import flatten_newtype
+from ..util.typing import is_generic
+from ..util.typing import is_literal
+from ..util.typing import is_newtype
+from ..util.typing import is_pep695
+from ..util.typing import Literal
+from ..util.typing import LITERAL_TYPES
+from ..util.typing import Self
+
+if TYPE_CHECKING:
+    from ._typing import _O
+    from ._typing import _RegistryType
+    from .decl_base import _DataclassArguments
+    from .instrumentation import ClassManager
+    from .interfaces import MapperProperty
+    from .state import InstanceState  # noqa
+    from ..sql._typing import _TypeEngineArgument
+    from ..sql.type_api import _MatchedOnType
+
+_T = TypeVar("_T", bound=Any)
+
+_TT = TypeVar("_TT", bound=Any)
+
+# it's not clear how to have Annotated, Union objects etc. as keys here
+# from a typing perspective so just leave it open ended for now
+_TypeAnnotationMapType = Mapping[Any, "_TypeEngineArgument[Any]"]
+_MutableTypeAnnotationMapType = Dict[Any, "_TypeEngineArgument[Any]"]
+
+_DeclaredAttrDecorated = Callable[
+    ..., Union[Mapped[_T], ORMDescriptor[_T], SQLCoreOperations[_T]]
+]
+
+
+def has_inherited_table(cls: Type[_O]) -> bool:
+    """Given a class, return True if any of the classes it inherits from has a
+    mapped table, otherwise return False.
+
+    This is used in declarative mixins to build attributes that behave
+    differently for the base class vs. a subclass in an inheritance
+    hierarchy.
+
+    .. seealso::
+
+        :ref:`decl_mixin_inheritance`
+
+    """
+    for class_ in cls.__mro__[1:]:
+        if getattr(class_, "__table__", None) is not None:
+            return True
+    return False
+
+
+class _DynamicAttributesType(type):
+    def __setattr__(cls, key: str, value: Any) -> None:
+        if "__mapper__" in cls.__dict__:
+            _add_attribute(cls, key, value)
+        else:
+            type.__setattr__(cls, key, value)
+
+    def __delattr__(cls, key: str) -> None:
+        if "__mapper__" in cls.__dict__:
+            _del_attribute(cls, key)
+        else:
+            type.__delattr__(cls, key)
+
+
+class DeclarativeAttributeIntercept(
+    _DynamicAttributesType,
+    # Inspectable is used only by the mypy plugin
+    inspection.Inspectable[Mapper[Any]],
+):
+    """Metaclass that may be used in conjunction with the
+    :class:`_orm.DeclarativeBase` class to support addition of class
+    attributes dynamically.
+
+    """
+
+
+@compat_typing.dataclass_transform(
+    field_specifiers=(
+        MappedColumn,
+        RelationshipProperty,
+        Composite,
+        Synonym,
+        mapped_column,
+        relationship,
+        composite,
+        synonym,
+        deferred,
+    ),
+)
+class DCTransformDeclarative(DeclarativeAttributeIntercept):
+    """metaclass that includes @dataclass_transforms"""
+
+
+class DeclarativeMeta(DeclarativeAttributeIntercept):
+    metadata: MetaData
+    registry: RegistryType
+
+    def __init__(
+        cls, classname: Any, bases: Any, dict_: Any, **kw: Any
+    ) -> None:
+        # use cls.__dict__, which can be modified by an
+        # __init_subclass__() method (#7900)
+        dict_ = cls.__dict__
+
+        # early-consume registry from the initial declarative base,
+        # assign privately to not conflict with subclass attributes named
+        # "registry"
+        reg = getattr(cls, "_sa_registry", None)
+        if reg is None:
+            reg = dict_.get("registry", None)
+            if not isinstance(reg, registry):
+                raise exc.InvalidRequestError(
+                    "Declarative base class has no 'registry' attribute, "
+                    "or registry is not a sqlalchemy.orm.registry() object"
+                )
+            else:
+                cls._sa_registry = reg
+
+        if not cls.__dict__.get("__abstract__", False):
+            _as_declarative(reg, cls, dict_)
+        type.__init__(cls, classname, bases, dict_)
+
+
+def synonym_for(
+    name: str, map_column: bool = False
+) -> Callable[[Callable[..., Any]], Synonym[Any]]:
+    """Decorator that produces an :func:`_orm.synonym`
+    attribute in conjunction with a Python descriptor.
+
+    The function being decorated is passed to :func:`_orm.synonym` as the
+    :paramref:`.orm.synonym.descriptor` parameter::
+
+        class MyClass(Base):
+            __tablename__ = "my_table"
+
+            id = Column(Integer, primary_key=True)
+            _job_status = Column("job_status", String(50))
+
+            @synonym_for("job_status")
+            @property
+            def job_status(self):
+                return "Status: %s" % self._job_status
+
+    The :ref:`hybrid properties <mapper_hybrids>` feature of SQLAlchemy
+    is typically preferred instead of synonyms, which is a more legacy
+    feature.
+
+    .. seealso::
+
+        :ref:`synonyms` - Overview of synonyms
+
+        :func:`_orm.synonym` - the mapper-level function
+
+        :ref:`mapper_hybrids` - The Hybrid Attribute extension provides an
+        updated approach to augmenting attribute behavior more flexibly than
+        can be achieved with synonyms.
+
+    """
+
+    def decorate(fn: Callable[..., Any]) -> Synonym[Any]:
+        return _orm_synonym(name, map_column=map_column, descriptor=fn)
+
+    return decorate
+
+
+class _declared_attr_common:
+    def __init__(
+        self,
+        fn: Callable[..., Any],
+        cascading: bool = False,
+        quiet: bool = False,
+    ):
+        # suppport
+        # @declared_attr
+        # @classmethod
+        # def foo(cls) -> Mapped[thing]:
+        #    ...
+        # which seems to help typing tools interpret the fn as a classmethod
+        # for situations where needed
+        if isinstance(fn, classmethod):
+            fn = fn.__func__
+
+        self.fget = fn
+        self._cascading = cascading
+        self._quiet = quiet
+        self.__doc__ = fn.__doc__
+
+    def _collect_return_annotation(self) -> Optional[Type[Any]]:
+        return util.get_annotations(self.fget).get("return")
+
+    def __get__(self, instance: Optional[object], owner: Any) -> Any:
+        # the declared_attr needs to make use of a cache that exists
+        # for the span of the declarative scan_attributes() phase.
+        # to achieve this we look at the class manager that's configured.
+
+        # note this method should not be called outside of the declarative
+        # setup phase
+
+        cls = owner
+        manager = attributes.opt_manager_of_class(cls)
+        if manager is None:
+            if not re.match(r"^__.+__$", self.fget.__name__):
+                # if there is no manager at all, then this class hasn't been
+                # run through declarative or mapper() at all, emit a warning.
+                util.warn(
+                    "Unmanaged access of declarative attribute %s from "
+                    "non-mapped class %s" % (self.fget.__name__, cls.__name__)
+                )
+            return self.fget(cls)
+        elif manager.is_mapped:
+            # the class is mapped, which means we're outside of the declarative
+            # scan setup, just run the function.
+            return self.fget(cls)
+
+        # here, we are inside of the declarative scan.  use the registry
+        # that is tracking the values of these attributes.
+        declarative_scan = manager.declarative_scan()
+
+        # assert that we are in fact in the declarative scan
+        assert declarative_scan is not None
+
+        reg = declarative_scan.declared_attr_reg
+
+        if self in reg:
+            return reg[self]
+        else:
+            reg[self] = obj = self.fget(cls)
+            return obj
+
+
+class _declared_directive(_declared_attr_common, Generic[_T]):
+    # see mapping_api.rst for docstring
+
+    if typing.TYPE_CHECKING:
+
+        def __init__(
+            self,
+            fn: Callable[..., _T],
+            cascading: bool = False,
+        ): ...
+
+        def __get__(self, instance: Optional[object], owner: Any) -> _T: ...
+
+        def __set__(self, instance: Any, value: Any) -> None: ...
+
+        def __delete__(self, instance: Any) -> None: ...
+
+        def __call__(self, fn: Callable[..., _TT]) -> _declared_directive[_TT]:
+            # extensive fooling of mypy underway...
+            ...
+
+
+class declared_attr(interfaces._MappedAttribute[_T], _declared_attr_common):
+    """Mark a class-level method as representing the definition of
+    a mapped property or Declarative directive.
+
+    :class:`_orm.declared_attr` is typically applied as a decorator to a class
+    level method, turning the attribute into a scalar-like property that can be
+    invoked from the uninstantiated class. The Declarative mapping process
+    looks for these :class:`_orm.declared_attr` callables as it scans classes,
+    and assumes any attribute marked with :class:`_orm.declared_attr` will be a
+    callable that will produce an object specific to the Declarative mapping or
+    table configuration.
+
+    :class:`_orm.declared_attr` is usually applicable to
+    :ref:`mixins <orm_mixins_toplevel>`, to define relationships that are to be
+    applied to different implementors of the class. It may also be used to
+    define dynamically generated column expressions and other Declarative
+    attributes.
+
+    Example::
+
+        class ProvidesUserMixin:
+            "A mixin that adds a 'user' relationship to classes."
+
+            user_id: Mapped[int] = mapped_column(ForeignKey("user_table.id"))
+
+            @declared_attr
+            def user(cls) -> Mapped["User"]:
+                return relationship("User")
+
+    When used with Declarative directives such as ``__tablename__``, the
+    :meth:`_orm.declared_attr.directive` modifier may be used which indicates
+    to :pep:`484` typing tools that the given method is not dealing with
+    :class:`_orm.Mapped` attributes::
+
+        class CreateTableName:
+            @declared_attr.directive
+            def __tablename__(cls) -> str:
+                return cls.__name__.lower()
+
+    :class:`_orm.declared_attr` can also be applied directly to mapped
+    classes, to allow for attributes that dynamically configure themselves
+    on subclasses when using mapped inheritance schemes.   Below
+    illustrates :class:`_orm.declared_attr` to create a dynamic scheme
+    for generating the :paramref:`_orm.Mapper.polymorphic_identity` parameter
+    for subclasses::
+
+        class Employee(Base):
+            __tablename__ = "employee"
+
+            id: Mapped[int] = mapped_column(primary_key=True)
+            type: Mapped[str] = mapped_column(String(50))
+
+            @declared_attr.directive
+            def __mapper_args__(cls) -> Dict[str, Any]:
+                if cls.__name__ == "Employee":
+                    return {
+                        "polymorphic_on": cls.type,
+                        "polymorphic_identity": "Employee",
+                    }
+                else:
+                    return {"polymorphic_identity": cls.__name__}
+
+
+        class Engineer(Employee):
+            pass
+
+    :class:`_orm.declared_attr` supports decorating functions that are
+    explicitly decorated with ``@classmethod``. This is never necessary from a
+    runtime perspective, however may be needed in order to support :pep:`484`
+    typing tools that don't otherwise recognize the decorated function as
+    having class-level behaviors for the ``cls`` parameter::
+
+        class SomethingMixin:
+            x: Mapped[int]
+            y: Mapped[int]
+
+            @declared_attr
+            @classmethod
+            def x_plus_y(cls) -> Mapped[int]:
+                return column_property(cls.x + cls.y)
+
+    .. versionadded:: 2.0 - :class:`_orm.declared_attr` can accommodate a
+       function decorated with ``@classmethod`` to help with :pep:`484`
+       integration where needed.
+
+
+    .. seealso::
+
+        :ref:`orm_mixins_toplevel` - Declarative Mixin documentation with
+        background on use patterns for :class:`_orm.declared_attr`.
+
+    """  # noqa: E501
+
+    if typing.TYPE_CHECKING:
+
+        def __init__(
+            self,
+            fn: _DeclaredAttrDecorated[_T],
+            cascading: bool = False,
+        ): ...
+
+        def __set__(self, instance: Any, value: Any) -> None: ...
+
+        def __delete__(self, instance: Any) -> None: ...
+
+        # this is the Mapped[] API where at class descriptor get time we want
+        # the type checker to see InstrumentedAttribute[_T].   However the
+        # callable function prior to mapping in fact calls the given
+        # declarative function that does not return InstrumentedAttribute
+        @overload
+        def __get__(
+            self, instance: None, owner: Any
+        ) -> InstrumentedAttribute[_T]: ...
+
+        @overload
+        def __get__(self, instance: object, owner: Any) -> _T: ...
+
+        def __get__(
+            self, instance: Optional[object], owner: Any
+        ) -> Union[InstrumentedAttribute[_T], _T]: ...
+
+    @hybridmethod
+    def _stateful(cls, **kw: Any) -> _stateful_declared_attr[_T]:
+        return _stateful_declared_attr(**kw)
+
+    @hybridproperty
+    def directive(cls) -> _declared_directive[Any]:
+        # see mapping_api.rst for docstring
+        return _declared_directive  # type: ignore
+
+    @hybridproperty
+    def cascading(cls) -> _stateful_declared_attr[_T]:
+        # see mapping_api.rst for docstring
+        return cls._stateful(cascading=True)
+
+
+class _stateful_declared_attr(declared_attr[_T]):
+    kw: Dict[str, Any]
+
+    def __init__(self, **kw: Any):
+        self.kw = kw
+
+    @hybridmethod
+    def _stateful(self, **kw: Any) -> _stateful_declared_attr[_T]:
+        new_kw = self.kw.copy()
+        new_kw.update(kw)
+        return _stateful_declared_attr(**new_kw)
+
+    def __call__(self, fn: _DeclaredAttrDecorated[_T]) -> declared_attr[_T]:
+        return declared_attr(fn, **self.kw)
+
+
+def declarative_mixin(cls: Type[_T]) -> Type[_T]:
+    """Mark a class as providing the feature of "declarative mixin".
+
+    E.g.::
+
+        from sqlalchemy.orm import declared_attr
+        from sqlalchemy.orm import declarative_mixin
+
+
+        @declarative_mixin
+        class MyMixin:
+
+            @declared_attr
+            def __tablename__(cls):
+                return cls.__name__.lower()
+
+            __table_args__ = {"mysql_engine": "InnoDB"}
+            __mapper_args__ = {"always_refresh": True}
+
+            id = Column(Integer, primary_key=True)
+
+
+        class MyModel(MyMixin, Base):
+            name = Column(String(1000))
+
+    The :func:`_orm.declarative_mixin` decorator currently does not modify
+    the given class in any way; it's current purpose is strictly to assist
+    the :ref:`Mypy plugin <mypy_toplevel>` in being able to identify
+    SQLAlchemy declarative mixin classes when no other context is present.
+
+    .. versionadded:: 1.4.6
+
+    .. seealso::
+
+        :ref:`orm_mixins_toplevel`
+
+        :ref:`mypy_declarative_mixins` - in the
+        :ref:`Mypy plugin documentation <mypy_toplevel>`
+
+    """  # noqa: E501
+
+    return cls
+
+
+def _setup_declarative_base(cls: Type[Any]) -> None:
+    if "metadata" in cls.__dict__:
+        metadata = cls.__dict__["metadata"]
+    else:
+        metadata = None
+
+    if "type_annotation_map" in cls.__dict__:
+        type_annotation_map = cls.__dict__["type_annotation_map"]
+    else:
+        type_annotation_map = None
+
+    reg = cls.__dict__.get("registry", None)
+    if reg is not None:
+        if not isinstance(reg, registry):
+            raise exc.InvalidRequestError(
+                "Declarative base class has a 'registry' attribute that is "
+                "not an instance of sqlalchemy.orm.registry()"
+            )
+        elif type_annotation_map is not None:
+            raise exc.InvalidRequestError(
+                "Declarative base class has both a 'registry' attribute and a "
+                "type_annotation_map entry.  Per-base type_annotation_maps "
+                "are not supported.  Please apply the type_annotation_map "
+                "to this registry directly."
+            )
+
+    else:
+        reg = registry(
+            metadata=metadata, type_annotation_map=type_annotation_map
+        )
+        cls.registry = reg
+
+    cls._sa_registry = reg
+
+    if "metadata" not in cls.__dict__:
+        cls.metadata = cls.registry.metadata
+
+    if getattr(cls, "__init__", object.__init__) is object.__init__:
+        cls.__init__ = cls.registry.constructor
+
+
+class MappedAsDataclass(metaclass=DCTransformDeclarative):
+    """Mixin class to indicate when mapping this class, also convert it to be
+    a dataclass.
+
+    .. seealso::
+
+        :ref:`orm_declarative_native_dataclasses` - complete background
+        on SQLAlchemy native dataclass mapping
+
+    .. versionadded:: 2.0
+
+    """
+
+    def __init_subclass__(
+        cls,
+        init: Union[_NoArg, bool] = _NoArg.NO_ARG,
+        repr: Union[_NoArg, bool] = _NoArg.NO_ARG,  # noqa: A002
+        eq: Union[_NoArg, bool] = _NoArg.NO_ARG,
+        order: Union[_NoArg, bool] = _NoArg.NO_ARG,
+        unsafe_hash: Union[_NoArg, bool] = _NoArg.NO_ARG,
+        match_args: Union[_NoArg, bool] = _NoArg.NO_ARG,
+        kw_only: Union[_NoArg, bool] = _NoArg.NO_ARG,
+        dataclass_callable: Union[
+            _NoArg, Callable[..., Type[Any]]
+        ] = _NoArg.NO_ARG,
+        **kw: Any,
+    ) -> None:
+        apply_dc_transforms: _DataclassArguments = {
+            "init": init,
+            "repr": repr,
+            "eq": eq,
+            "order": order,
+            "unsafe_hash": unsafe_hash,
+            "match_args": match_args,
+            "kw_only": kw_only,
+            "dataclass_callable": dataclass_callable,
+        }
+
+        current_transforms: _DataclassArguments
+
+        if hasattr(cls, "_sa_apply_dc_transforms"):
+            current = cls._sa_apply_dc_transforms
+
+            _ClassScanMapperConfig._assert_dc_arguments(current)
+
+            cls._sa_apply_dc_transforms = current_transforms = {  # type: ignore  # noqa: E501
+                k: current.get(k, _NoArg.NO_ARG) if v is _NoArg.NO_ARG else v
+                for k, v in apply_dc_transforms.items()
+            }
+        else:
+            cls._sa_apply_dc_transforms = current_transforms = (
+                apply_dc_transforms
+            )
+
+        super().__init_subclass__(**kw)
+
+        if not _is_mapped_class(cls):
+            new_anno = (
+                _ClassScanMapperConfig._update_annotations_for_non_mapped_class
+            )(cls)
+            _ClassScanMapperConfig._apply_dataclasses_to_any_class(
+                current_transforms, cls, new_anno
+            )
+
+
+class DeclarativeBase(
+    # Inspectable is used only by the mypy plugin
+    inspection.Inspectable[InstanceState[Any]],
+    metaclass=DeclarativeAttributeIntercept,
+):
+    """Base class used for declarative class definitions.
+
+    The :class:`_orm.DeclarativeBase` allows for the creation of new
+    declarative bases in such a way that is compatible with type checkers::
+
+
+        from sqlalchemy.orm import DeclarativeBase
+
+
+        class Base(DeclarativeBase):
+            pass
+
+    The above ``Base`` class is now usable as the base for new declarative
+    mappings.  The superclass makes use of the ``__init_subclass__()``
+    method to set up new classes and metaclasses aren't used.
+
+    When first used, the :class:`_orm.DeclarativeBase` class instantiates a new
+    :class:`_orm.registry` to be used with the base, assuming one was not
+    provided explicitly. The :class:`_orm.DeclarativeBase` class supports
+    class-level attributes which act as parameters for the construction of this
+    registry; such as to indicate a specific :class:`_schema.MetaData`
+    collection as well as a specific value for
+    :paramref:`_orm.registry.type_annotation_map`::
+
+        from typing_extensions import Annotated
+
+        from sqlalchemy import BigInteger
+        from sqlalchemy import MetaData
+        from sqlalchemy import String
+        from sqlalchemy.orm import DeclarativeBase
+
+        bigint = Annotated[int, "bigint"]
+        my_metadata = MetaData()
+
+
+        class Base(DeclarativeBase):
+            metadata = my_metadata
+            type_annotation_map = {
+                str: String().with_variant(String(255), "mysql", "mariadb"),
+                bigint: BigInteger(),
+            }
+
+    Class-level attributes which may be specified include:
+
+    :param metadata: optional :class:`_schema.MetaData` collection.
+     If a :class:`_orm.registry` is constructed automatically, this
+     :class:`_schema.MetaData` collection will be used to construct it.
+     Otherwise, the local :class:`_schema.MetaData` collection will supercede
+     that used by an existing :class:`_orm.registry` passed using the
+     :paramref:`_orm.DeclarativeBase.registry` parameter.
+    :param type_annotation_map: optional type annotation map that will be
+     passed to the :class:`_orm.registry` as
+     :paramref:`_orm.registry.type_annotation_map`.
+    :param registry: supply a pre-existing :class:`_orm.registry` directly.
+
+    .. versionadded:: 2.0  Added :class:`.DeclarativeBase`, so that declarative
+       base classes may be constructed in such a way that is also recognized
+       by :pep:`484` type checkers.   As a result, :class:`.DeclarativeBase`
+       and other subclassing-oriented APIs should be seen as
+       superseding previous "class returned by a function" APIs, namely
+       :func:`_orm.declarative_base` and :meth:`_orm.registry.generate_base`,
+       where the base class returned cannot be recognized by type checkers
+       without using plugins.
+
+    **__init__ behavior**
+
+    In a plain Python class, the base-most ``__init__()`` method in the class
+    hierarchy is ``object.__init__()``, which accepts no arguments. However,
+    when the :class:`_orm.DeclarativeBase` subclass is first declared, the
+    class is given an ``__init__()`` method that links to the
+    :paramref:`_orm.registry.constructor` constructor function, if no
+    ``__init__()`` method is already present; this is the usual declarative
+    constructor that will assign keyword arguments as attributes on the
+    instance, assuming those attributes are established at the class level
+    (i.e. are mapped, or are linked to a descriptor). This constructor is
+    **never accessed by a mapped class without being called explicitly via
+    super()**, as mapped classes are themselves given an ``__init__()`` method
+    directly which calls :paramref:`_orm.registry.constructor`, so in the
+    default case works independently of what the base-most ``__init__()``
+    method does.
+
+    .. versionchanged:: 2.0.1  :class:`_orm.DeclarativeBase` has a default
+       constructor that links to :paramref:`_orm.registry.constructor` by
+       default, so that calls to ``super().__init__()`` can access this
+       constructor. Previously, due to an implementation mistake, this default
+       constructor was missing, and calling ``super().__init__()`` would invoke
+       ``object.__init__()``.
+
+    The :class:`_orm.DeclarativeBase` subclass may also declare an explicit
+    ``__init__()`` method which will replace the use of the
+    :paramref:`_orm.registry.constructor` function at this level::
+
+        class Base(DeclarativeBase):
+            def __init__(self, id=None):
+                self.id = id
+
+    Mapped classes still will not invoke this constructor implicitly; it
+    remains only accessible by calling ``super().__init__()``::
+
+        class MyClass(Base):
+            def __init__(self, id=None, name=None):
+                self.name = name
+                super().__init__(id=id)
+
+    Note that this is a different behavior from what functions like the legacy
+    :func:`_orm.declarative_base` would do; the base created by those functions
+    would always install :paramref:`_orm.registry.constructor` for
+    ``__init__()``.
+
+
+    """
+
+    if typing.TYPE_CHECKING:
+
+        def _sa_inspect_type(self) -> Mapper[Self]: ...
+
+        def _sa_inspect_instance(self) -> InstanceState[Self]: ...
+
+        _sa_registry: ClassVar[_RegistryType]
+
+        registry: ClassVar[_RegistryType]
+        """Refers to the :class:`_orm.registry` in use where new
+        :class:`_orm.Mapper` objects will be associated."""
+
+        metadata: ClassVar[MetaData]
+        """Refers to the :class:`_schema.MetaData` collection that will be used
+        for new :class:`_schema.Table` objects.
+
+        .. seealso::
+
+            :ref:`orm_declarative_metadata`
+
+        """
+
+        __name__: ClassVar[str]
+
+        # this ideally should be Mapper[Self], but mypy as of 1.4.1 does not
+        # like it, and breaks the declared_attr_one test. Pyright/pylance is
+        # ok with it.
+        __mapper__: ClassVar[Mapper[Any]]
+        """The :class:`_orm.Mapper` object to which a particular class is
+        mapped.
+
+        May also be acquired using :func:`_sa.inspect`, e.g.
+        ``inspect(klass)``.
+
+        """
+
+        __table__: ClassVar[FromClause]
+        """The :class:`_sql.FromClause` to which a particular subclass is
+        mapped.
+
+        This is usually an instance of :class:`_schema.Table` but may also
+        refer to other kinds of :class:`_sql.FromClause` such as
+        :class:`_sql.Subquery`, depending on how the class is mapped.
+
+        .. seealso::
+
+            :ref:`orm_declarative_metadata`
+
+        """
+
+        # pyright/pylance do not consider a classmethod a ClassVar so use Any
+        # https://github.com/microsoft/pylance-release/issues/3484
+        __tablename__: Any
+        """String name to assign to the generated
+        :class:`_schema.Table` object, if not specified directly via
+        :attr:`_orm.DeclarativeBase.__table__`.
+
+        .. seealso::
+
+            :ref:`orm_declarative_table`
+
+        """
+
+        __mapper_args__: Any
+        """Dictionary of arguments which will be passed to the
+        :class:`_orm.Mapper` constructor.
+
+        .. seealso::
+
+            :ref:`orm_declarative_mapper_options`
+
+        """
+
+        __table_args__: Any
+        """A dictionary or tuple of arguments that will be passed to the
+        :class:`_schema.Table` constructor.  See
+        :ref:`orm_declarative_table_configuration`
+        for background on the specific structure of this collection.
+
+        .. seealso::
+
+            :ref:`orm_declarative_table_configuration`
+
+        """
+
+        def __init__(self, **kw: Any): ...
+
+    def __init_subclass__(cls, **kw: Any) -> None:
+        if DeclarativeBase in cls.__bases__:
+            _check_not_declarative(cls, DeclarativeBase)
+            _setup_declarative_base(cls)
+        else:
+            _as_declarative(cls._sa_registry, cls, cls.__dict__)
+        super().__init_subclass__(**kw)
+
+
+def _check_not_declarative(cls: Type[Any], base: Type[Any]) -> None:
+    cls_dict = cls.__dict__
+    if (
+        "__table__" in cls_dict
+        and not (
+            callable(cls_dict["__table__"])
+            or hasattr(cls_dict["__table__"], "__get__")
+        )
+    ) or isinstance(cls_dict.get("__tablename__", None), str):
+        raise exc.InvalidRequestError(
+            f"Cannot use {base.__name__!r} directly as a declarative base "
+            "class. Create a Base by creating a subclass of it."
+        )
+
+
+class DeclarativeBaseNoMeta(
+    # Inspectable is used only by the mypy plugin
+    inspection.Inspectable[InstanceState[Any]]
+):
+    """Same as :class:`_orm.DeclarativeBase`, but does not use a metaclass
+    to intercept new attributes.
+
+    The :class:`_orm.DeclarativeBaseNoMeta` base may be used when use of
+    custom metaclasses is desirable.
+
+    .. versionadded:: 2.0
+
+
+    """
+
+    _sa_registry: ClassVar[_RegistryType]
+
+    registry: ClassVar[_RegistryType]
+    """Refers to the :class:`_orm.registry` in use where new
+    :class:`_orm.Mapper` objects will be associated."""
+
+    metadata: ClassVar[MetaData]
+    """Refers to the :class:`_schema.MetaData` collection that will be used
+    for new :class:`_schema.Table` objects.
+
+    .. seealso::
+
+        :ref:`orm_declarative_metadata`
+
+    """
+
+    # this ideally should be Mapper[Self], but mypy as of 1.4.1 does not
+    # like it, and breaks the declared_attr_one test. Pyright/pylance is
+    # ok with it.
+    __mapper__: ClassVar[Mapper[Any]]
+    """The :class:`_orm.Mapper` object to which a particular class is
+    mapped.
+
+    May also be acquired using :func:`_sa.inspect`, e.g.
+    ``inspect(klass)``.
+
+    """
+
+    __table__: Optional[FromClause]
+    """The :class:`_sql.FromClause` to which a particular subclass is
+    mapped.
+
+    This is usually an instance of :class:`_schema.Table` but may also
+    refer to other kinds of :class:`_sql.FromClause` such as
+    :class:`_sql.Subquery`, depending on how the class is mapped.
+
+    .. seealso::
+
+        :ref:`orm_declarative_metadata`
+
+    """
+
+    if typing.TYPE_CHECKING:
+
+        def _sa_inspect_type(self) -> Mapper[Self]: ...
+
+        def _sa_inspect_instance(self) -> InstanceState[Self]: ...
+
+        __tablename__: Any
+        """String name to assign to the generated
+        :class:`_schema.Table` object, if not specified directly via
+        :attr:`_orm.DeclarativeBase.__table__`.
+
+        .. seealso::
+
+            :ref:`orm_declarative_table`
+
+        """
+
+        __mapper_args__: Any
+        """Dictionary of arguments which will be passed to the
+        :class:`_orm.Mapper` constructor.
+
+        .. seealso::
+
+            :ref:`orm_declarative_mapper_options`
+
+        """
+
+        __table_args__: Any
+        """A dictionary or tuple of arguments that will be passed to the
+        :class:`_schema.Table` constructor.  See
+        :ref:`orm_declarative_table_configuration`
+        for background on the specific structure of this collection.
+
+        .. seealso::
+
+            :ref:`orm_declarative_table_configuration`
+
+        """
+
+        def __init__(self, **kw: Any): ...
+
+    def __init_subclass__(cls, **kw: Any) -> None:
+        if DeclarativeBaseNoMeta in cls.__bases__:
+            _check_not_declarative(cls, DeclarativeBaseNoMeta)
+            _setup_declarative_base(cls)
+        else:
+            _as_declarative(cls._sa_registry, cls, cls.__dict__)
+        super().__init_subclass__(**kw)
+
+
+def add_mapped_attribute(
+    target: Type[_O], key: str, attr: MapperProperty[Any]
+) -> None:
+    """Add a new mapped attribute to an ORM mapped class.
+
+    E.g.::
+
+        add_mapped_attribute(User, "addresses", relationship(Address))
+
+    This may be used for ORM mappings that aren't using a declarative
+    metaclass that intercepts attribute set operations.
+
+    .. versionadded:: 2.0
+
+
+    """
+    _add_attribute(target, key, attr)
+
+
+def declarative_base(
+    *,
+    metadata: Optional[MetaData] = None,
+    mapper: Optional[Callable[..., Mapper[Any]]] = None,
+    cls: Type[Any] = object,
+    name: str = "Base",
+    class_registry: Optional[clsregistry._ClsRegistryType] = None,
+    type_annotation_map: Optional[_TypeAnnotationMapType] = None,
+    constructor: Callable[..., None] = _declarative_constructor,
+    metaclass: Type[Any] = DeclarativeMeta,
+) -> Any:
+    r"""Construct a base class for declarative class definitions.
+
+    The new base class will be given a metaclass that produces
+    appropriate :class:`~sqlalchemy.schema.Table` objects and makes
+    the appropriate :class:`_orm.Mapper` calls based on the
+    information provided declaratively in the class and any subclasses
+    of the class.
+
+    .. versionchanged:: 2.0 Note that the :func:`_orm.declarative_base`
+       function is superseded by the new :class:`_orm.DeclarativeBase` class,
+       which generates a new "base" class using subclassing, rather than
+       return value of a function.  This allows an approach that is compatible
+       with :pep:`484` typing tools.
+
+    The :func:`_orm.declarative_base` function is a shorthand version
+    of using the :meth:`_orm.registry.generate_base`
+    method.  That is, the following::
+
+        from sqlalchemy.orm import declarative_base
+
+        Base = declarative_base()
+
+    Is equivalent to::
+
+        from sqlalchemy.orm import registry
+
+        mapper_registry = registry()
+        Base = mapper_registry.generate_base()
+
+    See the docstring for :class:`_orm.registry`
+    and :meth:`_orm.registry.generate_base`
+    for more details.
+
+    .. versionchanged:: 1.4  The :func:`_orm.declarative_base`
+       function is now a specialization of the more generic
+       :class:`_orm.registry` class.  The function also moves to the
+       ``sqlalchemy.orm`` package from the ``declarative.ext`` package.
+
+
+    :param metadata:
+      An optional :class:`~sqlalchemy.schema.MetaData` instance.  All
+      :class:`~sqlalchemy.schema.Table` objects implicitly declared by
+      subclasses of the base will share this MetaData.  A MetaData instance
+      will be created if none is provided.  The
+      :class:`~sqlalchemy.schema.MetaData` instance will be available via the
+      ``metadata`` attribute of the generated declarative base class.
+
+    :param mapper:
+      An optional callable, defaults to :class:`_orm.Mapper`. Will
+      be used to map subclasses to their Tables.
+
+    :param cls:
+      Defaults to :class:`object`. A type to use as the base for the generated
+      declarative base class. May be a class or tuple of classes.
+
+    :param name:
+      Defaults to ``Base``.  The display name for the generated
+      class.  Customizing this is not required, but can improve clarity in
+      tracebacks and debugging.
+
+    :param constructor:
+      Specify the implementation for the ``__init__`` function on a mapped
+      class that has no ``__init__`` of its own.  Defaults to an
+      implementation that assigns \**kwargs for declared
+      fields and relationships to an instance.  If ``None`` is supplied,
+      no __init__ will be provided and construction will fall back to
+      cls.__init__ by way of the normal Python semantics.
+
+    :param class_registry: optional dictionary that will serve as the
+      registry of class names-> mapped classes when string names
+      are used to identify classes inside of :func:`_orm.relationship`
+      and others.  Allows two or more declarative base classes
+      to share the same registry of class names for simplified
+      inter-base relationships.
+
+    :param type_annotation_map: optional dictionary of Python types to
+        SQLAlchemy :class:`_types.TypeEngine` classes or instances.  This
+        is used exclusively by the :class:`_orm.MappedColumn` construct
+        to produce column types based on annotations within the
+        :class:`_orm.Mapped` type.
+
+
+        .. versionadded:: 2.0
+
+        .. seealso::
+
+            :ref:`orm_declarative_mapped_column_type_map`
+
+    :param metaclass:
+      Defaults to :class:`.DeclarativeMeta`.  A metaclass or __metaclass__
+      compatible callable to use as the meta type of the generated
+      declarative base class.
+
+    .. seealso::
+
+        :class:`_orm.registry`
+
+    """
+
+    return registry(
+        metadata=metadata,
+        class_registry=class_registry,
+        constructor=constructor,
+        type_annotation_map=type_annotation_map,
+    ).generate_base(
+        mapper=mapper,
+        cls=cls,
+        name=name,
+        metaclass=metaclass,
+    )
+
+
+class registry:
+    """Generalized registry for mapping classes.
+
+    The :class:`_orm.registry` serves as the basis for maintaining a collection
+    of mappings, and provides configurational hooks used to map classes.
+
+    The three general kinds of mappings supported are Declarative Base,
+    Declarative Decorator, and Imperative Mapping.   All of these mapping
+    styles may be used interchangeably:
+
+    * :meth:`_orm.registry.generate_base` returns a new declarative base
+      class, and is the underlying implementation of the
+      :func:`_orm.declarative_base` function.
+
+    * :meth:`_orm.registry.mapped` provides a class decorator that will
+      apply declarative mapping to a class without the use of a declarative
+      base class.
+
+    * :meth:`_orm.registry.map_imperatively` will produce a
+      :class:`_orm.Mapper` for a class without scanning the class for
+      declarative class attributes. This method suits the use case historically
+      provided by the ``sqlalchemy.orm.mapper()`` classical mapping function,
+      which is removed as of SQLAlchemy 2.0.
+
+    .. versionadded:: 1.4
+
+    .. seealso::
+
+        :ref:`orm_mapping_classes_toplevel` - overview of class mapping
+        styles.
+
+    """
+
+    _class_registry: clsregistry._ClsRegistryType
+    _managers: weakref.WeakKeyDictionary[ClassManager[Any], Literal[True]]
+    _non_primary_mappers: weakref.WeakKeyDictionary[Mapper[Any], Literal[True]]
+    metadata: MetaData
+    constructor: CallableReference[Callable[..., None]]
+    type_annotation_map: _MutableTypeAnnotationMapType
+    _dependents: Set[_RegistryType]
+    _dependencies: Set[_RegistryType]
+    _new_mappers: bool
+
+    def __init__(
+        self,
+        *,
+        metadata: Optional[MetaData] = None,
+        class_registry: Optional[clsregistry._ClsRegistryType] = None,
+        type_annotation_map: Optional[_TypeAnnotationMapType] = None,
+        constructor: Callable[..., None] = _declarative_constructor,
+    ):
+        r"""Construct a new :class:`_orm.registry`
+
+        :param metadata:
+          An optional :class:`_schema.MetaData` instance.  All
+          :class:`_schema.Table` objects generated using declarative
+          table mapping will make use of this :class:`_schema.MetaData`
+          collection.  If this argument is left at its default of ``None``,
+          a blank :class:`_schema.MetaData` collection is created.
+
+        :param constructor:
+          Specify the implementation for the ``__init__`` function on a mapped
+          class that has no ``__init__`` of its own.  Defaults to an
+          implementation that assigns \**kwargs for declared
+          fields and relationships to an instance.  If ``None`` is supplied,
+          no __init__ will be provided and construction will fall back to
+          cls.__init__ by way of the normal Python semantics.
+
+        :param class_registry: optional dictionary that will serve as the
+          registry of class names-> mapped classes when string names
+          are used to identify classes inside of :func:`_orm.relationship`
+          and others.  Allows two or more declarative base classes
+          to share the same registry of class names for simplified
+          inter-base relationships.
+
+        :param type_annotation_map: optional dictionary of Python types to
+          SQLAlchemy :class:`_types.TypeEngine` classes or instances.
+          The provided dict will update the default type mapping.  This
+          is used exclusively by the :class:`_orm.MappedColumn` construct
+          to produce column types based on annotations within the
+          :class:`_orm.Mapped` type.
+
+          .. versionadded:: 2.0
+
+          .. seealso::
+
+              :ref:`orm_declarative_mapped_column_type_map`
+
+
+        """
+        lcl_metadata = metadata or MetaData()
+
+        if class_registry is None:
+            class_registry = weakref.WeakValueDictionary()
+
+        self._class_registry = class_registry
+        self._managers = weakref.WeakKeyDictionary()
+        self._non_primary_mappers = weakref.WeakKeyDictionary()
+        self.metadata = lcl_metadata
+        self.constructor = constructor
+        self.type_annotation_map = {}
+        if type_annotation_map is not None:
+            self.update_type_annotation_map(type_annotation_map)
+        self._dependents = set()
+        self._dependencies = set()
+
+        self._new_mappers = False
+
+        with mapperlib._CONFIGURE_MUTEX:
+            mapperlib._mapper_registries[self] = True
+
+    def update_type_annotation_map(
+        self,
+        type_annotation_map: _TypeAnnotationMapType,
+    ) -> None:
+        """update the :paramref:`_orm.registry.type_annotation_map` with new
+        values."""
+
+        self.type_annotation_map.update(
+            {
+                de_optionalize_union_types(typ): sqltype
+                for typ, sqltype in type_annotation_map.items()
+            }
+        )
+
+    def _resolve_type(
+        self, python_type: _MatchedOnType, _do_fallbacks: bool = True
+    ) -> Optional[sqltypes.TypeEngine[Any]]:
+        python_type_type: Type[Any]
+        search: Iterable[Tuple[_MatchedOnType, Type[Any]]]
+
+        if is_generic(python_type):
+            if is_literal(python_type):
+                python_type_type = python_type  # type: ignore[assignment]
+
+                search = (
+                    (python_type, python_type_type),
+                    *((lt, python_type_type) for lt in LITERAL_TYPES),  # type: ignore[arg-type] # noqa: E501
+                )
+            else:
+                python_type_type = python_type.__origin__
+                search = ((python_type, python_type_type),)
+        elif isinstance(python_type, type):
+            python_type_type = python_type
+            search = ((pt, pt) for pt in python_type_type.__mro__)
+        else:
+            python_type_type = python_type  # type: ignore[assignment]
+            search = ((python_type, python_type_type),)
+
+        for pt, flattened in search:
+            # we search through full __mro__ for types.  however...
+            sql_type = self.type_annotation_map.get(pt)
+            if sql_type is None:
+                sql_type = sqltypes._type_map_get(pt)  # type: ignore  # noqa: E501
+
+            if sql_type is not None:
+                sql_type_inst = sqltypes.to_instance(sql_type)
+
+                # ... this additional step will reject most
+                # type -> supertype matches, such as if we had
+                # a MyInt(int) subclass.  note also we pass NewType()
+                # here directly; these always have to be in the
+                # type_annotation_map to be useful
+                resolved_sql_type = sql_type_inst._resolve_for_python_type(
+                    python_type_type,
+                    pt,
+                    flattened,
+                )
+                if resolved_sql_type is not None:
+                    return resolved_sql_type
+
+        # 2.0 fallbacks
+        if _do_fallbacks:
+            python_type_to_check: Any = None
+            kind = None
+            if is_pep695(python_type):
+                # NOTE: assume there aren't type alias types of new types.
+                python_type_to_check = python_type
+                while is_pep695(python_type_to_check):
+                    python_type_to_check = python_type_to_check.__value__
+                python_type_to_check = de_optionalize_union_types(
+                    python_type_to_check
+                )
+                kind = "TypeAliasType"
+            if is_newtype(python_type):
+                python_type_to_check = flatten_newtype(python_type)
+                kind = "NewType"
+
+            if python_type_to_check is not None:
+                res_after_fallback = self._resolve_type(
+                    python_type_to_check, False
+                )
+                if res_after_fallback is not None:
+                    assert kind is not None
+                    warn_deprecated(
+                        f"Matching the provided {kind} '{python_type}' on "
+                        "its resolved value without matching it in the "
+                        "type_annotation_map is deprecated; add this type to "
+                        "the type_annotation_map to allow it to match "
+                        "explicitly.",
+                        "2.0",
+                    )
+                    return res_after_fallback
+
+        return None
+
+    @property
+    def mappers(self) -> FrozenSet[Mapper[Any]]:
+        """read only collection of all :class:`_orm.Mapper` objects."""
+
+        return frozenset(manager.mapper for manager in self._managers).union(
+            self._non_primary_mappers
+        )
+
+    def _set_depends_on(self, registry: RegistryType) -> None:
+        if registry is self:
+            return
+        registry._dependents.add(self)
+        self._dependencies.add(registry)
+
+    def _flag_new_mapper(self, mapper: Mapper[Any]) -> None:
+        mapper._ready_for_configure = True
+        if self._new_mappers:
+            return
+
+        for reg in self._recurse_with_dependents({self}):
+            reg._new_mappers = True
+
+    @classmethod
+    def _recurse_with_dependents(
+        cls, registries: Set[RegistryType]
+    ) -> Iterator[RegistryType]:
+        todo = registries
+        done = set()
+        while todo:
+            reg = todo.pop()
+            done.add(reg)
+
+            # if yielding would remove dependents, make sure we have
+            # them before
+            todo.update(reg._dependents.difference(done))
+            yield reg
+
+            # if yielding would add dependents, make sure we have them
+            # after
+            todo.update(reg._dependents.difference(done))
+
+    @classmethod
+    def _recurse_with_dependencies(
+        cls, registries: Set[RegistryType]
+    ) -> Iterator[RegistryType]:
+        todo = registries
+        done = set()
+        while todo:
+            reg = todo.pop()
+            done.add(reg)
+
+            # if yielding would remove dependencies, make sure we have
+            # them before
+            todo.update(reg._dependencies.difference(done))
+
+            yield reg
+
+            # if yielding would remove dependencies, make sure we have
+            # them before
+            todo.update(reg._dependencies.difference(done))
+
+    def _mappers_to_configure(self) -> Iterator[Mapper[Any]]:
+        return itertools.chain(
+            (
+                manager.mapper
+                for manager in list(self._managers)
+                if manager.is_mapped
+                and not manager.mapper.configured
+                and manager.mapper._ready_for_configure
+            ),
+            (
+                npm
+                for npm in list(self._non_primary_mappers)
+                if not npm.configured and npm._ready_for_configure
+            ),
+        )
+
+    def _add_non_primary_mapper(self, np_mapper: Mapper[Any]) -> None:
+        self._non_primary_mappers[np_mapper] = True
+
+    def _dispose_cls(self, cls: Type[_O]) -> None:
+        clsregistry.remove_class(cls.__name__, cls, self._class_registry)
+
+    def _add_manager(self, manager: ClassManager[Any]) -> None:
+        self._managers[manager] = True
+        if manager.is_mapped:
+            raise exc.ArgumentError(
+                "Class '%s' already has a primary mapper defined. "
+                % manager.class_
+            )
+        assert manager.registry is None
+        manager.registry = self
+
+    def configure(self, cascade: bool = False) -> None:
+        """Configure all as-yet unconfigured mappers in this
+        :class:`_orm.registry`.
+
+        The configure step is used to reconcile and initialize the
+        :func:`_orm.relationship` linkages between mapped classes, as well as
+        to invoke configuration events such as the
+        :meth:`_orm.MapperEvents.before_configured` and
+        :meth:`_orm.MapperEvents.after_configured`, which may be used by ORM
+        extensions or user-defined extension hooks.
+
+        If one or more mappers in this registry contain
+        :func:`_orm.relationship` constructs that refer to mapped classes in
+        other registries, this registry is said to be *dependent* on those
+        registries. In order to configure those dependent registries
+        automatically, the :paramref:`_orm.registry.configure.cascade` flag
+        should be set to ``True``. Otherwise, if they are not configured, an
+        exception will be raised.  The rationale behind this behavior is to
+        allow an application to programmatically invoke configuration of
+        registries while controlling whether or not the process implicitly
+        reaches other registries.
+
+        As an alternative to invoking :meth:`_orm.registry.configure`, the ORM
+        function :func:`_orm.configure_mappers` function may be used to ensure
+        configuration is complete for all :class:`_orm.registry` objects in
+        memory. This is generally simpler to use and also predates the usage of
+        :class:`_orm.registry` objects overall. However, this function will
+        impact all mappings throughout the running Python process and may be
+        more memory/time consuming for an application that has many registries
+        in use for different purposes that may not be needed immediately.
+
+        .. seealso::
+
+            :func:`_orm.configure_mappers`
+
+
+        .. versionadded:: 1.4.0b2
+
+        """
+        mapperlib._configure_registries({self}, cascade=cascade)
+
+    def dispose(self, cascade: bool = False) -> None:
+        """Dispose of all mappers in this :class:`_orm.registry`.
+
+        After invocation, all the classes that were mapped within this registry
+        will no longer have class instrumentation associated with them. This
+        method is the per-:class:`_orm.registry` analogue to the
+        application-wide :func:`_orm.clear_mappers` function.
+
+        If this registry contains mappers that are dependencies of other
+        registries, typically via :func:`_orm.relationship` links, then those
+        registries must be disposed as well. When such registries exist in
+        relation to this one, their :meth:`_orm.registry.dispose` method will
+        also be called, if the :paramref:`_orm.registry.dispose.cascade` flag
+        is set to ``True``; otherwise, an error is raised if those registries
+        were not already disposed.
+
+        .. versionadded:: 1.4.0b2
+
+        .. seealso::
+
+            :func:`_orm.clear_mappers`
+
+        """
+
+        mapperlib._dispose_registries({self}, cascade=cascade)
+
+    def _dispose_manager_and_mapper(self, manager: ClassManager[Any]) -> None:
+        if "mapper" in manager.__dict__:
+            mapper = manager.mapper
+
+            mapper._set_dispose_flags()
+
+        class_ = manager.class_
+        self._dispose_cls(class_)
+        instrumentation._instrumentation_factory.unregister(class_)
+
+    def generate_base(
+        self,
+        mapper: Optional[Callable[..., Mapper[Any]]] = None,
+        cls: Type[Any] = object,
+        name: str = "Base",
+        metaclass: Type[Any] = DeclarativeMeta,
+    ) -> Any:
+        """Generate a declarative base class.
+
+        Classes that inherit from the returned class object will be
+        automatically mapped using declarative mapping.
+
+        E.g.::
+
+            from sqlalchemy.orm import registry
+
+            mapper_registry = registry()
+
+            Base = mapper_registry.generate_base()
+
+
+            class MyClass(Base):
+                __tablename__ = "my_table"
+                id = Column(Integer, primary_key=True)
+
+        The above dynamically generated class is equivalent to the
+        non-dynamic example below::
+
+            from sqlalchemy.orm import registry
+            from sqlalchemy.orm.decl_api import DeclarativeMeta
+
+            mapper_registry = registry()
+
+
+            class Base(metaclass=DeclarativeMeta):
+                __abstract__ = True
+                registry = mapper_registry
+                metadata = mapper_registry.metadata
+
+                __init__ = mapper_registry.constructor
+
+        .. versionchanged:: 2.0 Note that the
+           :meth:`_orm.registry.generate_base` method is superseded by the new
+           :class:`_orm.DeclarativeBase` class, which generates a new "base"
+           class using subclassing, rather than return value of a function.
+           This allows an approach that is compatible with :pep:`484` typing
+           tools.
+
+        The :meth:`_orm.registry.generate_base` method provides the
+        implementation for the :func:`_orm.declarative_base` function, which
+        creates the :class:`_orm.registry` and base class all at once.
+
+        See the section :ref:`orm_declarative_mapping` for background and
+        examples.
+
+        :param mapper:
+          An optional callable, defaults to :class:`_orm.Mapper`.
+          This function is used to generate new :class:`_orm.Mapper` objects.
+
+        :param cls:
+          Defaults to :class:`object`. A type to use as the base for the
+          generated declarative base class. May be a class or tuple of classes.
+
+        :param name:
+          Defaults to ``Base``.  The display name for the generated
+          class.  Customizing this is not required, but can improve clarity in
+          tracebacks and debugging.
+
+        :param metaclass:
+          Defaults to :class:`.DeclarativeMeta`.  A metaclass or __metaclass__
+          compatible callable to use as the meta type of the generated
+          declarative base class.
+
+        .. seealso::
+
+            :ref:`orm_declarative_mapping`
+
+            :func:`_orm.declarative_base`
+
+        """
+        metadata = self.metadata
+
+        bases = not isinstance(cls, tuple) and (cls,) or cls
+
+        class_dict: Dict[str, Any] = dict(registry=self, metadata=metadata)
+        if isinstance(cls, type):
+            class_dict["__doc__"] = cls.__doc__
+
+        if self.constructor is not None:
+            class_dict["__init__"] = self.constructor
+
+        class_dict["__abstract__"] = True
+        if mapper:
+            class_dict["__mapper_cls__"] = mapper
+
+        if hasattr(cls, "__class_getitem__"):
+
+            def __class_getitem__(cls: Type[_T], key: Any) -> Type[_T]:
+                # allow generic classes in py3.9+
+                return cls
+
+            class_dict["__class_getitem__"] = __class_getitem__
+
+        return metaclass(name, bases, class_dict)
+
+    @compat_typing.dataclass_transform(
+        field_specifiers=(
+            MappedColumn,
+            RelationshipProperty,
+            Composite,
+            Synonym,
+            mapped_column,
+            relationship,
+            composite,
+            synonym,
+            deferred,
+        ),
+    )
+    @overload
+    def mapped_as_dataclass(self, __cls: Type[_O]) -> Type[_O]: ...
+
+    @overload
+    def mapped_as_dataclass(
+        self,
+        __cls: Literal[None] = ...,
+        *,
+        init: Union[_NoArg, bool] = ...,
+        repr: Union[_NoArg, bool] = ...,  # noqa: A002
+        eq: Union[_NoArg, bool] = ...,
+        order: Union[_NoArg, bool] = ...,
+        unsafe_hash: Union[_NoArg, bool] = ...,
+        match_args: Union[_NoArg, bool] = ...,
+        kw_only: Union[_NoArg, bool] = ...,
+        dataclass_callable: Union[_NoArg, Callable[..., Type[Any]]] = ...,
+    ) -> Callable[[Type[_O]], Type[_O]]: ...
+
+    def mapped_as_dataclass(
+        self,
+        __cls: Optional[Type[_O]] = None,
+        *,
+        init: Union[_NoArg, bool] = _NoArg.NO_ARG,
+        repr: Union[_NoArg, bool] = _NoArg.NO_ARG,  # noqa: A002
+        eq: Union[_NoArg, bool] = _NoArg.NO_ARG,
+        order: Union[_NoArg, bool] = _NoArg.NO_ARG,
+        unsafe_hash: Union[_NoArg, bool] = _NoArg.NO_ARG,
+        match_args: Union[_NoArg, bool] = _NoArg.NO_ARG,
+        kw_only: Union[_NoArg, bool] = _NoArg.NO_ARG,
+        dataclass_callable: Union[
+            _NoArg, Callable[..., Type[Any]]
+        ] = _NoArg.NO_ARG,
+    ) -> Union[Type[_O], Callable[[Type[_O]], Type[_O]]]:
+        """Class decorator that will apply the Declarative mapping process
+        to a given class, and additionally convert the class to be a
+        Python dataclass.
+
+        .. seealso::
+
+            :ref:`orm_declarative_native_dataclasses` - complete background
+            on SQLAlchemy native dataclass mapping
+
+
+        .. versionadded:: 2.0
+
+
+        """
+
+        def decorate(cls: Type[_O]) -> Type[_O]:
+            setattr(
+                cls,
+                "_sa_apply_dc_transforms",
+                {
+                    "init": init,
+                    "repr": repr,
+                    "eq": eq,
+                    "order": order,
+                    "unsafe_hash": unsafe_hash,
+                    "match_args": match_args,
+                    "kw_only": kw_only,
+                    "dataclass_callable": dataclass_callable,
+                },
+            )
+            _as_declarative(self, cls, cls.__dict__)
+            return cls
+
+        if __cls:
+            return decorate(__cls)
+        else:
+            return decorate
+
+    def mapped(self, cls: Type[_O]) -> Type[_O]:
+        """Class decorator that will apply the Declarative mapping process
+        to a given class.
+
+        E.g.::
+
+            from sqlalchemy.orm import registry
+
+            mapper_registry = registry()
+
+
+            @mapper_registry.mapped
+            class Foo:
+                __tablename__ = "some_table"
+
+                id = Column(Integer, primary_key=True)
+                name = Column(String)
+
+        See the section :ref:`orm_declarative_mapping` for complete
+        details and examples.
+
+        :param cls: class to be mapped.
+
+        :return: the class that was passed.
+
+        .. seealso::
+
+            :ref:`orm_declarative_mapping`
+
+            :meth:`_orm.registry.generate_base` - generates a base class
+            that will apply Declarative mapping to subclasses automatically
+            using a Python metaclass.
+
+        .. seealso::
+
+            :meth:`_orm.registry.mapped_as_dataclass`
+
+        """
+        _as_declarative(self, cls, cls.__dict__)
+        return cls
+
+    def as_declarative_base(self, **kw: Any) -> Callable[[Type[_T]], Type[_T]]:
+        """
+        Class decorator which will invoke
+        :meth:`_orm.registry.generate_base`
+        for a given base class.
+
+        E.g.::
+
+            from sqlalchemy.orm import registry
+
+            mapper_registry = registry()
+
+
+            @mapper_registry.as_declarative_base()
+            class Base:
+                @declared_attr
+                def __tablename__(cls):
+                    return cls.__name__.lower()
+
+                id = Column(Integer, primary_key=True)
+
+
+            class MyMappedClass(Base): ...
+
+        All keyword arguments passed to
+        :meth:`_orm.registry.as_declarative_base` are passed
+        along to :meth:`_orm.registry.generate_base`.
+
+        """
+
+        def decorate(cls: Type[_T]) -> Type[_T]:
+            kw["cls"] = cls
+            kw["name"] = cls.__name__
+            return self.generate_base(**kw)  # type: ignore
+
+        return decorate
+
+    def map_declaratively(self, cls: Type[_O]) -> Mapper[_O]:
+        """Map a class declaratively.
+
+        In this form of mapping, the class is scanned for mapping information,
+        including for columns to be associated with a table, and/or an
+        actual table object.
+
+        Returns the :class:`_orm.Mapper` object.
+
+        E.g.::
+
+            from sqlalchemy.orm import registry
+
+            mapper_registry = registry()
+
+
+            class Foo:
+                __tablename__ = "some_table"
+
+                id = Column(Integer, primary_key=True)
+                name = Column(String)
+
+
+            mapper = mapper_registry.map_declaratively(Foo)
+
+        This function is more conveniently invoked indirectly via either the
+        :meth:`_orm.registry.mapped` class decorator or by subclassing a
+        declarative metaclass generated from
+        :meth:`_orm.registry.generate_base`.
+
+        See the section :ref:`orm_declarative_mapping` for complete
+        details and examples.
+
+        :param cls: class to be mapped.
+
+        :return: a :class:`_orm.Mapper` object.
+
+        .. seealso::
+
+            :ref:`orm_declarative_mapping`
+
+            :meth:`_orm.registry.mapped` - more common decorator interface
+            to this function.
+
+            :meth:`_orm.registry.map_imperatively`
+
+        """
+        _as_declarative(self, cls, cls.__dict__)
+        return cls.__mapper__  # type: ignore
+
+    def map_imperatively(
+        self,
+        class_: Type[_O],
+        local_table: Optional[FromClause] = None,
+        **kw: Any,
+    ) -> Mapper[_O]:
+        r"""Map a class imperatively.
+
+        In this form of mapping, the class is not scanned for any mapping
+        information.  Instead, all mapping constructs are passed as
+        arguments.
+
+        This method is intended to be fully equivalent to the now-removed
+        SQLAlchemy ``mapper()`` function, except that it's in terms of
+        a particular registry.
+
+        E.g.::
+
+            from sqlalchemy.orm import registry
+
+            mapper_registry = registry()
+
+            my_table = Table(
+                "my_table",
+                mapper_registry.metadata,
+                Column("id", Integer, primary_key=True),
+            )
+
+
+            class MyClass:
+                pass
+
+
+            mapper_registry.map_imperatively(MyClass, my_table)
+
+        See the section :ref:`orm_imperative_mapping` for complete background
+        and usage examples.
+
+        :param class\_: The class to be mapped.  Corresponds to the
+         :paramref:`_orm.Mapper.class_` parameter.
+
+        :param local_table: the :class:`_schema.Table` or other
+         :class:`_sql.FromClause` object that is the subject of the mapping.
+         Corresponds to the
+         :paramref:`_orm.Mapper.local_table` parameter.
+
+        :param \**kw: all other keyword arguments are passed to the
+         :class:`_orm.Mapper` constructor directly.
+
+        .. seealso::
+
+            :ref:`orm_imperative_mapping`
+
+            :ref:`orm_declarative_mapping`
+
+        """
+        return _mapper(self, class_, local_table, kw)
+
+
+RegistryType = registry
+
+if not TYPE_CHECKING:
+    # allow for runtime type resolution of ``ClassVar[_RegistryType]``
+    _RegistryType = registry  # noqa
+
+
+def as_declarative(**kw: Any) -> Callable[[Type[_T]], Type[_T]]:
+    """
+    Class decorator which will adapt a given class into a
+    :func:`_orm.declarative_base`.
+
+    This function makes use of the :meth:`_orm.registry.as_declarative_base`
+    method, by first creating a :class:`_orm.registry` automatically
+    and then invoking the decorator.
+
+    E.g.::
+
+        from sqlalchemy.orm import as_declarative
+
+
+        @as_declarative()
+        class Base:
+            @declared_attr
+            def __tablename__(cls):
+                return cls.__name__.lower()
+
+            id = Column(Integer, primary_key=True)
+
+
+        class MyMappedClass(Base): ...
+
+    .. seealso::
+
+        :meth:`_orm.registry.as_declarative_base`
+
+    """
+    metadata, class_registry = (
+        kw.pop("metadata", None),
+        kw.pop("class_registry", None),
+    )
+
+    return registry(
+        metadata=metadata, class_registry=class_registry
+    ).as_declarative_base(**kw)
+
+
+@inspection._inspects(
+    DeclarativeMeta, DeclarativeBase, DeclarativeAttributeIntercept
+)
+def _inspect_decl_meta(cls: Type[Any]) -> Optional[Mapper[Any]]:
+    mp: Optional[Mapper[Any]] = _inspect_mapped_class(cls)
+    if mp is None:
+        if _DeferredMapperConfig.has_cls(cls):
+            _DeferredMapperConfig.raise_unmapped_for_cls(cls)
+    return mp