1# orm/decl_api.py 
    2# Copyright (C) 2005-2025 the SQLAlchemy authors and contributors 
    3# <see AUTHORS file> 
    4# 
    5# This module is part of SQLAlchemy and is released under 
    6# the MIT License: https://www.opensource.org/licenses/mit-license.php 
    7 
    8"""Public API functions and helpers for declarative.""" 
    9 
    10from __future__ import annotations 
    11 
    12import re 
    13import typing 
    14from typing import Any 
    15from typing import Callable 
    16from typing import ClassVar 
    17from typing import Dict 
    18from typing import FrozenSet 
    19from typing import Generic 
    20from typing import Iterable 
    21from typing import Iterator 
    22from typing import Literal 
    23from typing import Mapping 
    24from typing import Optional 
    25from typing import overload 
    26from typing import Set 
    27from typing import Tuple 
    28from typing import Type 
    29from typing import TYPE_CHECKING 
    30from typing import TypeVar 
    31from typing import Union 
    32import weakref 
    33 
    34from . import attributes 
    35from . import clsregistry 
    36from . import instrumentation 
    37from . import interfaces 
    38from . import mapperlib 
    39from ._orm_constructors import composite 
    40from ._orm_constructors import deferred 
    41from ._orm_constructors import mapped_column 
    42from ._orm_constructors import relationship 
    43from ._orm_constructors import synonym 
    44from .attributes import InstrumentedAttribute 
    45from .base import _inspect_mapped_class 
    46from .base import _is_mapped_class 
    47from .base import Mapped 
    48from .base import ORMDescriptor 
    49from .decl_base import _add_attribute 
    50from .decl_base import _declarative_constructor 
    51from .decl_base import _DeclarativeMapperConfig 
    52from .decl_base import _DeferredDeclarativeConfig 
    53from .decl_base import _del_attribute 
    54from .decl_base import _ORMClassConfigurator 
    55from .descriptor_props import Composite 
    56from .descriptor_props import Synonym 
    57from .descriptor_props import Synonym as _orm_synonym 
    58from .mapper import Mapper 
    59from .properties import MappedColumn 
    60from .relationships import RelationshipProperty 
    61from .state import InstanceState 
    62from .. import exc 
    63from .. import inspection 
    64from .. import util 
    65from ..event import dispatcher 
    66from ..event import EventTarget 
    67from ..sql import sqltypes 
    68from ..sql.base import _NoArg 
    69from ..sql.elements import SQLCoreOperations 
    70from ..sql.schema import MetaData 
    71from ..sql.selectable import FromClause 
    72from ..util import hybridmethod 
    73from ..util import hybridproperty 
    74from ..util import typing as compat_typing 
    75from ..util.typing import CallableReference 
    76from ..util.typing import de_optionalize_union_types 
    77from ..util.typing import GenericProtocol 
    78from ..util.typing import is_generic 
    79from ..util.typing import is_literal 
    80from ..util.typing import LITERAL_TYPES 
    81from ..util.typing import Self 
    82from ..util.typing import TypeAliasType 
    83 
    84if TYPE_CHECKING: 
    85    from ._typing import _O 
    86    from ._typing import _RegistryType 
    87    from .instrumentation import ClassManager 
    88    from .interfaces import _DataclassArguments 
    89    from .interfaces import MapperProperty 
    90    from .state import InstanceState  # noqa 
    91    from ..sql._typing import _TypeEngineArgument 
    92    from ..util.typing import _MatchedOnType 
    93 
    94_T = TypeVar("_T", bound=Any) 
    95 
    96_TT = TypeVar("_TT", bound=Any) 
    97 
    98# it's not clear how to have Annotated, Union objects etc. as keys here 
    99# from a typing perspective so just leave it open ended for now 
    100_TypeAnnotationMapType = Mapping[Any, "_TypeEngineArgument[Any]"] 
    101_MutableTypeAnnotationMapType = Dict[Any, "_TypeEngineArgument[Any]"] 
    102 
    103_DeclaredAttrDecorated = Callable[ 
    104    ..., Union[Mapped[_T], ORMDescriptor[_T], SQLCoreOperations[_T]] 
    105] 
    106 
    107 
    108def has_inherited_table(cls: Type[_O]) -> bool: 
    109    """Given a class, return True if any of the classes it inherits from has a 
    110    mapped table, otherwise return False. 
    111 
    112    This is used in declarative mixins to build attributes that behave 
    113    differently for the base class vs. a subclass in an inheritance 
    114    hierarchy. 
    115 
    116    .. seealso:: 
    117 
    118        :ref:`decl_mixin_inheritance` 
    119 
    120    """ 
    121    for class_ in cls.__mro__[1:]: 
    122        if getattr(class_, "__table__", None) is not None: 
    123            return True 
    124    return False 
    125 
    126 
    127class _DynamicAttributesType(type): 
    128    def __setattr__(cls, key: str, value: Any) -> None: 
    129        if "__mapper__" in cls.__dict__: 
    130            _add_attribute(cls, key, value) 
    131        else: 
    132            type.__setattr__(cls, key, value) 
    133 
    134    def __delattr__(cls, key: str) -> None: 
    135        if "__mapper__" in cls.__dict__: 
    136            _del_attribute(cls, key) 
    137        else: 
    138            type.__delattr__(cls, key) 
    139 
    140 
    141class DeclarativeAttributeIntercept( 
    142    _DynamicAttributesType, 
    143    # Inspectable is used only by the mypy plugin 
    144    inspection.Inspectable[Mapper[Any]], 
    145): 
    146    """Metaclass that may be used in conjunction with the 
    147    :class:`_orm.DeclarativeBase` class to support addition of class 
    148    attributes dynamically. 
    149 
    150    """ 
    151 
    152 
    153@compat_typing.dataclass_transform( 
    154    field_specifiers=( 
    155        MappedColumn, 
    156        RelationshipProperty, 
    157        Composite, 
    158        Synonym, 
    159        mapped_column, 
    160        relationship, 
    161        composite, 
    162        synonym, 
    163        deferred, 
    164    ), 
    165) 
    166class DCTransformDeclarative(DeclarativeAttributeIntercept): 
    167    """metaclass that includes @dataclass_transforms""" 
    168 
    169 
    170class DeclarativeMeta(DeclarativeAttributeIntercept): 
    171    metadata: MetaData 
    172    registry: RegistryType 
    173 
    174    def __init__( 
    175        cls, classname: Any, bases: Any, dict_: Any, **kw: Any 
    176    ) -> None: 
    177        # use cls.__dict__, which can be modified by an 
    178        # __init_subclass__() method (#7900) 
    179        dict_ = cls.__dict__ 
    180 
    181        # early-consume registry from the initial declarative base, 
    182        # assign privately to not conflict with subclass attributes named 
    183        # "registry" 
    184        reg = getattr(cls, "_sa_registry", None) 
    185        if reg is None: 
    186            reg = dict_.get("registry", None) 
    187            if not isinstance(reg, registry): 
    188                raise exc.InvalidRequestError( 
    189                    "Declarative base class has no 'registry' attribute, " 
    190                    "or registry is not a sqlalchemy.orm.registry() object" 
    191                ) 
    192            else: 
    193                cls._sa_registry = reg 
    194 
    195        if not cls.__dict__.get("__abstract__", False): 
    196            _ORMClassConfigurator._as_declarative(reg, cls, dict_) 
    197        type.__init__(cls, classname, bases, dict_) 
    198 
    199 
    200def synonym_for( 
    201    name: str, map_column: bool = False 
    202) -> Callable[[Callable[..., Any]], Synonym[Any]]: 
    203    """Decorator that produces an :func:`_orm.synonym` 
    204    attribute in conjunction with a Python descriptor. 
    205 
    206    The function being decorated is passed to :func:`_orm.synonym` as the 
    207    :paramref:`.orm.synonym.descriptor` parameter:: 
    208 
    209        class MyClass(Base): 
    210            __tablename__ = "my_table" 
    211 
    212            id = Column(Integer, primary_key=True) 
    213            _job_status = Column("job_status", String(50)) 
    214 
    215            @synonym_for("job_status") 
    216            @property 
    217            def job_status(self): 
    218                return "Status: %s" % self._job_status 
    219 
    220    The :ref:`hybrid properties <mapper_hybrids>` feature of SQLAlchemy 
    221    is typically preferred instead of synonyms, which is a more legacy 
    222    feature. 
    223 
    224    .. seealso:: 
    225 
    226        :ref:`synonyms` - Overview of synonyms 
    227 
    228        :func:`_orm.synonym` - the mapper-level function 
    229 
    230        :ref:`mapper_hybrids` - The Hybrid Attribute extension provides an 
    231        updated approach to augmenting attribute behavior more flexibly than 
    232        can be achieved with synonyms. 
    233 
    234    """ 
    235 
    236    def decorate(fn: Callable[..., Any]) -> Synonym[Any]: 
    237        return _orm_synonym(name, map_column=map_column, descriptor=fn) 
    238 
    239    return decorate 
    240 
    241 
    242class _declared_attr_common: 
    243    def __init__( 
    244        self, 
    245        fn: Callable[..., Any], 
    246        cascading: bool = False, 
    247        quiet: bool = False, 
    248    ): 
    249        # suppport 
    250        # @declared_attr 
    251        # @classmethod 
    252        # def foo(cls) -> Mapped[thing]: 
    253        #    ... 
    254        # which seems to help typing tools interpret the fn as a classmethod 
    255        # for situations where needed 
    256        if isinstance(fn, classmethod): 
    257            fn = fn.__func__ 
    258 
    259        self.fget = fn 
    260        self._cascading = cascading 
    261        self._quiet = quiet 
    262        self.__doc__ = fn.__doc__ 
    263 
    264    def _collect_return_annotation(self) -> Optional[Type[Any]]: 
    265        return util.get_annotations(self.fget).get("return") 
    266 
    267    def __get__(self, instance: Optional[object], owner: Any) -> Any: 
    268        # the declared_attr needs to make use of a cache that exists 
    269        # for the span of the declarative scan_attributes() phase. 
    270        # to achieve this we look at the class manager that's configured. 
    271 
    272        # note this method should not be called outside of the declarative 
    273        # setup phase 
    274 
    275        cls = owner 
    276        manager = attributes.opt_manager_of_class(cls) 
    277        if manager is None: 
    278            if not re.match(r"^__.+__$", self.fget.__name__): 
    279                # if there is no manager at all, then this class hasn't been 
    280                # run through declarative or mapper() at all, emit a warning. 
    281                util.warn( 
    282                    "Unmanaged access of declarative attribute %s from " 
    283                    "non-mapped class %s" % (self.fget.__name__, cls.__name__) 
    284                ) 
    285            return self.fget(cls) 
    286        elif manager.is_mapped: 
    287            # the class is mapped, which means we're outside of the declarative 
    288            # scan setup, just run the function. 
    289            return self.fget(cls) 
    290 
    291        # here, we are inside of the declarative scan.  use the registry 
    292        # that is tracking the values of these attributes. 
    293        declarative_scan = manager.declarative_scan() 
    294 
    295        # assert that we are in fact in the declarative scan 
    296        assert declarative_scan is not None 
    297 
    298        reg = declarative_scan.declared_attr_reg 
    299 
    300        if self in reg: 
    301            return reg[self] 
    302        else: 
    303            reg[self] = obj = self.fget(cls) 
    304            return obj 
    305 
    306 
    307class _declared_directive(_declared_attr_common, Generic[_T]): 
    308    # see mapping_api.rst for docstring 
    309 
    310    if typing.TYPE_CHECKING: 
    311 
    312        def __init__( 
    313            self, 
    314            fn: Callable[..., _T], 
    315            cascading: bool = False, 
    316        ): ... 
    317 
    318        def __get__(self, instance: Optional[object], owner: Any) -> _T: ... 
    319 
    320        def __set__(self, instance: Any, value: Any) -> None: ... 
    321 
    322        def __delete__(self, instance: Any) -> None: ... 
    323 
    324        def __call__(self, fn: Callable[..., _TT]) -> _declared_directive[_TT]: 
    325            # extensive fooling of mypy underway... 
    326            ... 
    327 
    328 
    329class declared_attr(interfaces._MappedAttribute[_T], _declared_attr_common): 
    330    """Mark a class-level method as representing the definition of 
    331    a mapped property or Declarative directive. 
    332 
    333    :class:`_orm.declared_attr` is typically applied as a decorator to a class 
    334    level method, turning the attribute into a scalar-like property that can be 
    335    invoked from the uninstantiated class. The Declarative mapping process 
    336    looks for these :class:`_orm.declared_attr` callables as it scans classes, 
    337    and assumes any attribute marked with :class:`_orm.declared_attr` will be a 
    338    callable that will produce an object specific to the Declarative mapping or 
    339    table configuration. 
    340 
    341    :class:`_orm.declared_attr` is usually applicable to 
    342    :ref:`mixins <orm_mixins_toplevel>`, to define relationships that are to be 
    343    applied to different implementors of the class. It may also be used to 
    344    define dynamically generated column expressions and other Declarative 
    345    attributes. 
    346 
    347    Example:: 
    348 
    349        class ProvidesUserMixin: 
    350            "A mixin that adds a 'user' relationship to classes." 
    351 
    352            user_id: Mapped[int] = mapped_column(ForeignKey("user_table.id")) 
    353 
    354            @declared_attr 
    355            def user(cls) -> Mapped["User"]: 
    356                return relationship("User") 
    357 
    358    When used with Declarative directives such as ``__tablename__``, the 
    359    :meth:`_orm.declared_attr.directive` modifier may be used which indicates 
    360    to :pep:`484` typing tools that the given method is not dealing with 
    361    :class:`_orm.Mapped` attributes:: 
    362 
    363        class CreateTableName: 
    364            @declared_attr.directive 
    365            def __tablename__(cls) -> str: 
    366                return cls.__name__.lower() 
    367 
    368    :class:`_orm.declared_attr` can also be applied directly to mapped 
    369    classes, to allow for attributes that dynamically configure themselves 
    370    on subclasses when using mapped inheritance schemes.   Below 
    371    illustrates :class:`_orm.declared_attr` to create a dynamic scheme 
    372    for generating the :paramref:`_orm.Mapper.polymorphic_identity` parameter 
    373    for subclasses:: 
    374 
    375        class Employee(Base): 
    376            __tablename__ = "employee" 
    377 
    378            id: Mapped[int] = mapped_column(primary_key=True) 
    379            type: Mapped[str] = mapped_column(String(50)) 
    380 
    381            @declared_attr.directive 
    382            def __mapper_args__(cls) -> Dict[str, Any]: 
    383                if cls.__name__ == "Employee": 
    384                    return { 
    385                        "polymorphic_on": cls.type, 
    386                        "polymorphic_identity": "Employee", 
    387                    } 
    388                else: 
    389                    return {"polymorphic_identity": cls.__name__} 
    390 
    391 
    392        class Engineer(Employee): 
    393            pass 
    394 
    395    :class:`_orm.declared_attr` supports decorating functions that are 
    396    explicitly decorated with ``@classmethod``. This is never necessary from a 
    397    runtime perspective, however may be needed in order to support :pep:`484` 
    398    typing tools that don't otherwise recognize the decorated function as 
    399    having class-level behaviors for the ``cls`` parameter:: 
    400 
    401        class SomethingMixin: 
    402            x: Mapped[int] 
    403            y: Mapped[int] 
    404 
    405            @declared_attr 
    406            @classmethod 
    407            def x_plus_y(cls) -> Mapped[int]: 
    408                return column_property(cls.x + cls.y) 
    409 
    410    .. versionadded:: 2.0 - :class:`_orm.declared_attr` can accommodate a 
    411       function decorated with ``@classmethod`` to help with :pep:`484` 
    412       integration where needed. 
    413 
    414 
    415    .. seealso:: 
    416 
    417        :ref:`orm_mixins_toplevel` - Declarative Mixin documentation with 
    418        background on use patterns for :class:`_orm.declared_attr`. 
    419 
    420    """  # noqa: E501 
    421 
    422    if typing.TYPE_CHECKING: 
    423 
    424        def __init__( 
    425            self, 
    426            fn: _DeclaredAttrDecorated[_T], 
    427            cascading: bool = False, 
    428        ): ... 
    429 
    430        def __set__(self, instance: Any, value: Any) -> None: ... 
    431 
    432        def __delete__(self, instance: Any) -> None: ... 
    433 
    434        # this is the Mapped[] API where at class descriptor get time we want 
    435        # the type checker to see InstrumentedAttribute[_T].   However the 
    436        # callable function prior to mapping in fact calls the given 
    437        # declarative function that does not return InstrumentedAttribute 
    438        @overload 
    439        def __get__( 
    440            self, instance: None, owner: Any 
    441        ) -> InstrumentedAttribute[_T]: ... 
    442 
    443        @overload 
    444        def __get__(self, instance: object, owner: Any) -> _T: ... 
    445 
    446        def __get__( 
    447            self, instance: Optional[object], owner: Any 
    448        ) -> Union[InstrumentedAttribute[_T], _T]: ... 
    449 
    450    @hybridmethod 
    451    def _stateful(cls, **kw: Any) -> _stateful_declared_attr[_T]: 
    452        return _stateful_declared_attr(**kw) 
    453 
    454    @hybridproperty 
    455    def directive(cls) -> _declared_directive[Any]: 
    456        # see mapping_api.rst for docstring 
    457        return _declared_directive  # type: ignore 
    458 
    459    @hybridproperty 
    460    def cascading(cls) -> _stateful_declared_attr[_T]: 
    461        # see mapping_api.rst for docstring 
    462        return cls._stateful(cascading=True) 
    463 
    464 
    465class _stateful_declared_attr(declared_attr[_T]): 
    466    kw: Dict[str, Any] 
    467 
    468    def __init__(self, **kw: Any): 
    469        self.kw = kw 
    470 
    471    @hybridmethod 
    472    def _stateful(self, **kw: Any) -> _stateful_declared_attr[_T]: 
    473        new_kw = self.kw.copy() 
    474        new_kw.update(kw) 
    475        return _stateful_declared_attr(**new_kw) 
    476 
    477    def __call__(self, fn: _DeclaredAttrDecorated[_T]) -> declared_attr[_T]: 
    478        return declared_attr(fn, **self.kw) 
    479 
    480 
    481@util.deprecated( 
    482    "2.1", 
    483    "The declarative_mixin decorator was used only by the now removed " 
    484    "mypy plugin so it has no longer any use and can be safely removed.", 
    485) 
    486def declarative_mixin(cls: Type[_T]) -> Type[_T]: 
    487    """Mark a class as providing the feature of "declarative mixin". 
    488 
    489    E.g.:: 
    490 
    491        from sqlalchemy.orm import declared_attr 
    492        from sqlalchemy.orm import declarative_mixin 
    493 
    494 
    495        @declarative_mixin 
    496        class MyMixin: 
    497 
    498            @declared_attr 
    499            def __tablename__(cls): 
    500                return cls.__name__.lower() 
    501 
    502            __table_args__ = {"mysql_engine": "InnoDB"} 
    503            __mapper_args__ = {"always_refresh": True} 
    504 
    505            id = Column(Integer, primary_key=True) 
    506 
    507 
    508        class MyModel(MyMixin, Base): 
    509            name = Column(String(1000)) 
    510 
    511    The :func:`_orm.declarative_mixin` decorator currently does not modify 
    512    the given class in any way; it's current purpose is strictly to assist 
    513    the Mypy plugin in being able to identify 
    514    SQLAlchemy declarative mixin classes when no other context is present. 
    515 
    516    .. versionadded:: 1.4.6 
    517 
    518    .. seealso:: 
    519 
    520        :ref:`orm_mixins_toplevel` 
    521 
    522    """  # noqa: E501 
    523 
    524    return cls 
    525 
    526 
    527def _setup_declarative_base(cls: Type[Any]) -> None: 
    528    if "metadata" in cls.__dict__: 
    529        metadata = cls.__dict__["metadata"] 
    530    else: 
    531        metadata = None 
    532 
    533    if "type_annotation_map" in cls.__dict__: 
    534        type_annotation_map = cls.__dict__["type_annotation_map"] 
    535    else: 
    536        type_annotation_map = None 
    537 
    538    reg = cls.__dict__.get("registry", None) 
    539    if reg is not None: 
    540        if not isinstance(reg, registry): 
    541            raise exc.InvalidRequestError( 
    542                "Declarative base class has a 'registry' attribute that is " 
    543                "not an instance of sqlalchemy.orm.registry()" 
    544            ) 
    545        elif type_annotation_map is not None: 
    546            raise exc.InvalidRequestError( 
    547                "Declarative base class has both a 'registry' attribute and a " 
    548                "type_annotation_map entry.  Per-base type_annotation_maps " 
    549                "are not supported.  Please apply the type_annotation_map " 
    550                "to this registry directly." 
    551            ) 
    552 
    553    else: 
    554        reg = registry( 
    555            metadata=metadata, type_annotation_map=type_annotation_map 
    556        ) 
    557        cls.registry = reg 
    558 
    559    cls._sa_registry = reg 
    560 
    561    if "metadata" not in cls.__dict__: 
    562        cls.metadata = cls.registry.metadata 
    563 
    564    if getattr(cls, "__init__", object.__init__) is object.__init__: 
    565        cls.__init__ = cls.registry.constructor 
    566 
    567 
    568def _generate_dc_transforms( 
    569    cls_: Type[_O], 
    570    init: Union[_NoArg, bool] = _NoArg.NO_ARG, 
    571    repr: Union[_NoArg, bool] = _NoArg.NO_ARG,  # noqa: A002 
    572    eq: Union[_NoArg, bool] = _NoArg.NO_ARG, 
    573    order: Union[_NoArg, bool] = _NoArg.NO_ARG, 
    574    unsafe_hash: Union[_NoArg, bool] = _NoArg.NO_ARG, 
    575    match_args: Union[_NoArg, bool] = _NoArg.NO_ARG, 
    576    kw_only: Union[_NoArg, bool] = _NoArg.NO_ARG, 
    577    dataclass_callable: Union[ 
    578        _NoArg, Callable[..., Type[Any]] 
    579    ] = _NoArg.NO_ARG, 
    580) -> None: 
    581    apply_dc_transforms: _DataclassArguments = { 
    582        "init": init, 
    583        "repr": repr, 
    584        "eq": eq, 
    585        "order": order, 
    586        "unsafe_hash": unsafe_hash, 
    587        "match_args": match_args, 
    588        "kw_only": kw_only, 
    589        "dataclass_callable": dataclass_callable, 
    590    } 
    591 
    592    if hasattr(cls_, "_sa_apply_dc_transforms"): 
    593        current = cls_._sa_apply_dc_transforms  # type: ignore[attr-defined] 
    594 
    595        _DeclarativeMapperConfig._assert_dc_arguments(current) 
    596 
    597        cls_._sa_apply_dc_transforms = {  # type: ignore  # noqa: E501 
    598            k: current.get(k, _NoArg.NO_ARG) if v is _NoArg.NO_ARG else v 
    599            for k, v in apply_dc_transforms.items() 
    600        } 
    601    else: 
    602        setattr(cls_, "_sa_apply_dc_transforms", apply_dc_transforms) 
    603 
    604 
    605class MappedAsDataclass(metaclass=DCTransformDeclarative): 
    606    """Mixin class to indicate when mapping this class, also convert it to be 
    607    a dataclass. 
    608 
    609    .. seealso:: 
    610 
    611        :ref:`orm_declarative_native_dataclasses` - complete background 
    612        on SQLAlchemy native dataclass mapping with 
    613        :class:`_orm.MappedAsDataclass`. 
    614 
    615        :ref:`orm_declarative_dc_mixins` - examples specific to using 
    616        :class:`_orm.MappedAsDataclass` to create mixins 
    617 
    618        :func:`_orm.mapped_as_dataclass` / :func:`_orm.unmapped_dataclass` - 
    619        decorator versions with equivalent functionality 
    620 
    621    .. versionadded:: 2.0 
    622 
    623    """ 
    624 
    625    def __init_subclass__( 
    626        cls, 
    627        init: Union[_NoArg, bool] = _NoArg.NO_ARG, 
    628        repr: Union[_NoArg, bool] = _NoArg.NO_ARG,  # noqa: A002 
    629        eq: Union[_NoArg, bool] = _NoArg.NO_ARG, 
    630        order: Union[_NoArg, bool] = _NoArg.NO_ARG, 
    631        unsafe_hash: Union[_NoArg, bool] = _NoArg.NO_ARG, 
    632        match_args: Union[_NoArg, bool] = _NoArg.NO_ARG, 
    633        kw_only: Union[_NoArg, bool] = _NoArg.NO_ARG, 
    634        dataclass_callable: Union[ 
    635            _NoArg, Callable[..., Type[Any]] 
    636        ] = _NoArg.NO_ARG, 
    637        **kw: Any, 
    638    ) -> None: 
    639        _generate_dc_transforms( 
    640            init=init, 
    641            repr=repr, 
    642            eq=eq, 
    643            order=order, 
    644            unsafe_hash=unsafe_hash, 
    645            match_args=match_args, 
    646            kw_only=kw_only, 
    647            dataclass_callable=dataclass_callable, 
    648            cls_=cls, 
    649        ) 
    650        super().__init_subclass__(**kw) 
    651 
    652        if not _is_mapped_class(cls): 
    653            # turn unmapped classes into "good enough" dataclasses to serve 
    654            # as a base or a mixin 
    655            _ORMClassConfigurator._as_unmapped_dataclass(cls, cls.__dict__) 
    656 
    657 
    658class DeclarativeBase( 
    659    # Inspectable is used only by the mypy plugin 
    660    inspection.Inspectable[InstanceState[Any]], 
    661    metaclass=DeclarativeAttributeIntercept, 
    662): 
    663    """Base class used for declarative class definitions. 
    664 
    665    The :class:`_orm.DeclarativeBase` allows for the creation of new 
    666    declarative bases in such a way that is compatible with type checkers:: 
    667 
    668 
    669        from sqlalchemy.orm import DeclarativeBase 
    670 
    671 
    672        class Base(DeclarativeBase): 
    673            pass 
    674 
    675    The above ``Base`` class is now usable as the base for new declarative 
    676    mappings.  The superclass makes use of the ``__init_subclass__()`` 
    677    method to set up new classes and metaclasses aren't used. 
    678 
    679    When first used, the :class:`_orm.DeclarativeBase` class instantiates a new 
    680    :class:`_orm.registry` to be used with the base, assuming one was not 
    681    provided explicitly. The :class:`_orm.DeclarativeBase` class supports 
    682    class-level attributes which act as parameters for the construction of this 
    683    registry; such as to indicate a specific :class:`_schema.MetaData` 
    684    collection as well as a specific value for 
    685    :paramref:`_orm.registry.type_annotation_map`:: 
    686 
    687        from typing import Annotated 
    688 
    689        from sqlalchemy import BigInteger 
    690        from sqlalchemy import MetaData 
    691        from sqlalchemy import String 
    692        from sqlalchemy.orm import DeclarativeBase 
    693 
    694        bigint = Annotated[int, "bigint"] 
    695        my_metadata = MetaData() 
    696 
    697 
    698        class Base(DeclarativeBase): 
    699            metadata = my_metadata 
    700            type_annotation_map = { 
    701                str: String().with_variant(String(255), "mysql", "mariadb"), 
    702                bigint: BigInteger(), 
    703            } 
    704 
    705    Class-level attributes which may be specified include: 
    706 
    707    :param metadata: optional :class:`_schema.MetaData` collection. 
    708     If a :class:`_orm.registry` is constructed automatically, this 
    709     :class:`_schema.MetaData` collection will be used to construct it. 
    710     Otherwise, the local :class:`_schema.MetaData` collection will supercede 
    711     that used by an existing :class:`_orm.registry` passed using the 
    712     :paramref:`_orm.DeclarativeBase.registry` parameter. 
    713    :param type_annotation_map: optional type annotation map that will be 
    714     passed to the :class:`_orm.registry` as 
    715     :paramref:`_orm.registry.type_annotation_map`. 
    716    :param registry: supply a pre-existing :class:`_orm.registry` directly. 
    717 
    718    .. versionadded:: 2.0  Added :class:`.DeclarativeBase`, so that declarative 
    719       base classes may be constructed in such a way that is also recognized 
    720       by :pep:`484` type checkers.   As a result, :class:`.DeclarativeBase` 
    721       and other subclassing-oriented APIs should be seen as 
    722       superseding previous "class returned by a function" APIs, namely 
    723       :func:`_orm.declarative_base` and :meth:`_orm.registry.generate_base`, 
    724       where the base class returned cannot be recognized by type checkers 
    725       without using plugins. 
    726 
    727    **__init__ behavior** 
    728 
    729    In a plain Python class, the base-most ``__init__()`` method in the class 
    730    hierarchy is ``object.__init__()``, which accepts no arguments. However, 
    731    when the :class:`_orm.DeclarativeBase` subclass is first declared, the 
    732    class is given an ``__init__()`` method that links to the 
    733    :paramref:`_orm.registry.constructor` constructor function, if no 
    734    ``__init__()`` method is already present; this is the usual declarative 
    735    constructor that will assign keyword arguments as attributes on the 
    736    instance, assuming those attributes are established at the class level 
    737    (i.e. are mapped, or are linked to a descriptor). This constructor is 
    738    **never accessed by a mapped class without being called explicitly via 
    739    super()**, as mapped classes are themselves given an ``__init__()`` method 
    740    directly which calls :paramref:`_orm.registry.constructor`, so in the 
    741    default case works independently of what the base-most ``__init__()`` 
    742    method does. 
    743 
    744    .. versionchanged:: 2.0.1  :class:`_orm.DeclarativeBase` has a default 
    745       constructor that links to :paramref:`_orm.registry.constructor` by 
    746       default, so that calls to ``super().__init__()`` can access this 
    747       constructor. Previously, due to an implementation mistake, this default 
    748       constructor was missing, and calling ``super().__init__()`` would invoke 
    749       ``object.__init__()``. 
    750 
    751    The :class:`_orm.DeclarativeBase` subclass may also declare an explicit 
    752    ``__init__()`` method which will replace the use of the 
    753    :paramref:`_orm.registry.constructor` function at this level:: 
    754 
    755        class Base(DeclarativeBase): 
    756            def __init__(self, id=None): 
    757                self.id = id 
    758 
    759    Mapped classes still will not invoke this constructor implicitly; it 
    760    remains only accessible by calling ``super().__init__()``:: 
    761 
    762        class MyClass(Base): 
    763            def __init__(self, id=None, name=None): 
    764                self.name = name 
    765                super().__init__(id=id) 
    766 
    767    Note that this is a different behavior from what functions like the legacy 
    768    :func:`_orm.declarative_base` would do; the base created by those functions 
    769    would always install :paramref:`_orm.registry.constructor` for 
    770    ``__init__()``. 
    771 
    772 
    773    """ 
    774 
    775    if typing.TYPE_CHECKING: 
    776 
    777        def _sa_inspect_type(self) -> Mapper[Self]: ... 
    778 
    779        def _sa_inspect_instance(self) -> InstanceState[Self]: ... 
    780 
    781        _sa_registry: ClassVar[_RegistryType] 
    782 
    783        registry: ClassVar[_RegistryType] 
    784        """Refers to the :class:`_orm.registry` in use where new 
    785        :class:`_orm.Mapper` objects will be associated.""" 
    786 
    787        metadata: ClassVar[MetaData] 
    788        """Refers to the :class:`_schema.MetaData` collection that will be used 
    789        for new :class:`_schema.Table` objects. 
    790 
    791        .. seealso:: 
    792 
    793            :ref:`orm_declarative_metadata` 
    794 
    795        """ 
    796 
    797        __name__: ClassVar[str] 
    798 
    799        # this ideally should be Mapper[Self], but mypy as of 1.4.1 does not 
    800        # like it, and breaks the declared_attr_one test. Pyright/pylance is 
    801        # ok with it. 
    802        __mapper__: ClassVar[Mapper[Any]] 
    803        """The :class:`_orm.Mapper` object to which a particular class is 
    804        mapped. 
    805 
    806        May also be acquired using :func:`_sa.inspect`, e.g. 
    807        ``inspect(klass)``. 
    808 
    809        """ 
    810 
    811        __table__: ClassVar[FromClause] 
    812        """The :class:`_sql.FromClause` to which a particular subclass is 
    813        mapped. 
    814 
    815        This is usually an instance of :class:`_schema.Table` but may also 
    816        refer to other kinds of :class:`_sql.FromClause` such as 
    817        :class:`_sql.Subquery`, depending on how the class is mapped. 
    818 
    819        .. seealso:: 
    820 
    821            :ref:`orm_declarative_metadata` 
    822 
    823        """ 
    824 
    825        # pyright/pylance do not consider a classmethod a ClassVar so use Any 
    826        # https://github.com/microsoft/pylance-release/issues/3484 
    827        __tablename__: Any 
    828        """String name to assign to the generated 
    829        :class:`_schema.Table` object, if not specified directly via 
    830        :attr:`_orm.DeclarativeBase.__table__`. 
    831 
    832        .. seealso:: 
    833 
    834            :ref:`orm_declarative_table` 
    835 
    836        """ 
    837 
    838        __mapper_args__: Any 
    839        """Dictionary of arguments which will be passed to the 
    840        :class:`_orm.Mapper` constructor. 
    841 
    842        .. seealso:: 
    843 
    844            :ref:`orm_declarative_mapper_options` 
    845 
    846        """ 
    847 
    848        __table_args__: Any 
    849        """A dictionary or tuple of arguments that will be passed to the 
    850        :class:`_schema.Table` constructor.  See 
    851        :ref:`orm_declarative_table_configuration` 
    852        for background on the specific structure of this collection. 
    853 
    854        .. seealso:: 
    855 
    856            :ref:`orm_declarative_table_configuration` 
    857 
    858        """ 
    859 
    860        def __init__(self, **kw: Any): ... 
    861 
    862    def __init_subclass__(cls, **kw: Any) -> None: 
    863        if DeclarativeBase in cls.__bases__: 
    864            _check_not_declarative(cls, DeclarativeBase) 
    865            _setup_declarative_base(cls) 
    866        else: 
    867            _ORMClassConfigurator._as_declarative( 
    868                cls._sa_registry, cls, cls.__dict__ 
    869            ) 
    870        super().__init_subclass__(**kw) 
    871 
    872 
    873def _check_not_declarative(cls: Type[Any], base: Type[Any]) -> None: 
    874    cls_dict = cls.__dict__ 
    875    if ( 
    876        "__table__" in cls_dict 
    877        and not ( 
    878            callable(cls_dict["__table__"]) 
    879            or hasattr(cls_dict["__table__"], "__get__") 
    880        ) 
    881    ) or isinstance(cls_dict.get("__tablename__", None), str): 
    882        raise exc.InvalidRequestError( 
    883            f"Cannot use {base.__name__!r} directly as a declarative base " 
    884            "class. Create a Base by creating a subclass of it." 
    885        ) 
    886 
    887 
    888class DeclarativeBaseNoMeta( 
    889    # Inspectable is used only by the mypy plugin 
    890    inspection.Inspectable[InstanceState[Any]] 
    891): 
    892    """Same as :class:`_orm.DeclarativeBase`, but does not use a metaclass 
    893    to intercept new attributes. 
    894 
    895    The :class:`_orm.DeclarativeBaseNoMeta` base may be used when use of 
    896    custom metaclasses is desirable. 
    897 
    898    .. versionadded:: 2.0 
    899 
    900 
    901    """ 
    902 
    903    _sa_registry: ClassVar[_RegistryType] 
    904 
    905    registry: ClassVar[_RegistryType] 
    906    """Refers to the :class:`_orm.registry` in use where new 
    907    :class:`_orm.Mapper` objects will be associated.""" 
    908 
    909    metadata: ClassVar[MetaData] 
    910    """Refers to the :class:`_schema.MetaData` collection that will be used 
    911    for new :class:`_schema.Table` objects. 
    912 
    913    .. seealso:: 
    914 
    915        :ref:`orm_declarative_metadata` 
    916 
    917    """ 
    918 
    919    # this ideally should be Mapper[Self], but mypy as of 1.4.1 does not 
    920    # like it, and breaks the declared_attr_one test. Pyright/pylance is 
    921    # ok with it. 
    922    __mapper__: ClassVar[Mapper[Any]] 
    923    """The :class:`_orm.Mapper` object to which a particular class is 
    924    mapped. 
    925 
    926    May also be acquired using :func:`_sa.inspect`, e.g. 
    927    ``inspect(klass)``. 
    928 
    929    """ 
    930 
    931    __table__: Optional[FromClause] 
    932    """The :class:`_sql.FromClause` to which a particular subclass is 
    933    mapped. 
    934 
    935    This is usually an instance of :class:`_schema.Table` but may also 
    936    refer to other kinds of :class:`_sql.FromClause` such as 
    937    :class:`_sql.Subquery`, depending on how the class is mapped. 
    938 
    939    .. seealso:: 
    940 
    941        :ref:`orm_declarative_metadata` 
    942 
    943    """ 
    944 
    945    if typing.TYPE_CHECKING: 
    946 
    947        def _sa_inspect_type(self) -> Mapper[Self]: ... 
    948 
    949        def _sa_inspect_instance(self) -> InstanceState[Self]: ... 
    950 
    951        __tablename__: Any 
    952        """String name to assign to the generated 
    953        :class:`_schema.Table` object, if not specified directly via 
    954        :attr:`_orm.DeclarativeBase.__table__`. 
    955 
    956        .. seealso:: 
    957 
    958            :ref:`orm_declarative_table` 
    959 
    960        """ 
    961 
    962        __mapper_args__: Any 
    963        """Dictionary of arguments which will be passed to the 
    964        :class:`_orm.Mapper` constructor. 
    965 
    966        .. seealso:: 
    967 
    968            :ref:`orm_declarative_mapper_options` 
    969 
    970        """ 
    971 
    972        __table_args__: Any 
    973        """A dictionary or tuple of arguments that will be passed to the 
    974        :class:`_schema.Table` constructor.  See 
    975        :ref:`orm_declarative_table_configuration` 
    976        for background on the specific structure of this collection. 
    977 
    978        .. seealso:: 
    979 
    980            :ref:`orm_declarative_table_configuration` 
    981 
    982        """ 
    983 
    984        def __init__(self, **kw: Any): ... 
    985 
    986    def __init_subclass__(cls, **kw: Any) -> None: 
    987        if DeclarativeBaseNoMeta in cls.__bases__: 
    988            _check_not_declarative(cls, DeclarativeBaseNoMeta) 
    989            _setup_declarative_base(cls) 
    990        else: 
    991            _ORMClassConfigurator._as_declarative( 
    992                cls._sa_registry, cls, cls.__dict__ 
    993            ) 
    994        super().__init_subclass__(**kw) 
    995 
    996 
    997def add_mapped_attribute( 
    998    target: Type[_O], key: str, attr: MapperProperty[Any] 
    999) -> None: 
    1000    """Add a new mapped attribute to an ORM mapped class. 
    1001 
    1002    E.g.:: 
    1003 
    1004        add_mapped_attribute(User, "addresses", relationship(Address)) 
    1005 
    1006    This may be used for ORM mappings that aren't using a declarative 
    1007    metaclass that intercepts attribute set operations. 
    1008 
    1009    .. versionadded:: 2.0 
    1010 
    1011 
    1012    """ 
    1013    _add_attribute(target, key, attr) 
    1014 
    1015 
    1016def declarative_base( 
    1017    *, 
    1018    metadata: Optional[MetaData] = None, 
    1019    mapper: Optional[Callable[..., Mapper[Any]]] = None, 
    1020    cls: Type[Any] = object, 
    1021    name: str = "Base", 
    1022    class_registry: Optional[clsregistry._ClsRegistryType] = None, 
    1023    type_annotation_map: Optional[_TypeAnnotationMapType] = None, 
    1024    constructor: Callable[..., None] = _declarative_constructor, 
    1025    metaclass: Type[Any] = DeclarativeMeta, 
    1026) -> Any: 
    1027    r"""Construct a base class for declarative class definitions. 
    1028 
    1029    The new base class will be given a metaclass that produces 
    1030    appropriate :class:`~sqlalchemy.schema.Table` objects and makes 
    1031    the appropriate :class:`_orm.Mapper` calls based on the 
    1032    information provided declaratively in the class and any subclasses 
    1033    of the class. 
    1034 
    1035    .. versionchanged:: 2.0 Note that the :func:`_orm.declarative_base` 
    1036       function is superseded by the new :class:`_orm.DeclarativeBase` class, 
    1037       which generates a new "base" class using subclassing, rather than 
    1038       return value of a function.  This allows an approach that is compatible 
    1039       with :pep:`484` typing tools. 
    1040 
    1041    The :func:`_orm.declarative_base` function is a shorthand version 
    1042    of using the :meth:`_orm.registry.generate_base` 
    1043    method.  That is, the following:: 
    1044 
    1045        from sqlalchemy.orm import declarative_base 
    1046 
    1047        Base = declarative_base() 
    1048 
    1049    Is equivalent to:: 
    1050 
    1051        from sqlalchemy.orm import registry 
    1052 
    1053        mapper_registry = registry() 
    1054        Base = mapper_registry.generate_base() 
    1055 
    1056    See the docstring for :class:`_orm.registry` 
    1057    and :meth:`_orm.registry.generate_base` 
    1058    for more details. 
    1059 
    1060    .. versionchanged:: 1.4  The :func:`_orm.declarative_base` 
    1061       function is now a specialization of the more generic 
    1062       :class:`_orm.registry` class.  The function also moves to the 
    1063       ``sqlalchemy.orm`` package from the ``declarative.ext`` package. 
    1064 
    1065 
    1066    :param metadata: 
    1067      An optional :class:`~sqlalchemy.schema.MetaData` instance.  All 
    1068      :class:`~sqlalchemy.schema.Table` objects implicitly declared by 
    1069      subclasses of the base will share this MetaData.  A MetaData instance 
    1070      will be created if none is provided.  The 
    1071      :class:`~sqlalchemy.schema.MetaData` instance will be available via the 
    1072      ``metadata`` attribute of the generated declarative base class. 
    1073 
    1074    :param mapper: 
    1075      An optional callable, defaults to :class:`_orm.Mapper`. Will 
    1076      be used to map subclasses to their Tables. 
    1077 
    1078    :param cls: 
    1079      Defaults to :class:`object`. A type to use as the base for the generated 
    1080      declarative base class. May be a class or tuple of classes. 
    1081 
    1082    :param name: 
    1083      Defaults to ``Base``.  The display name for the generated 
    1084      class.  Customizing this is not required, but can improve clarity in 
    1085      tracebacks and debugging. 
    1086 
    1087    :param constructor: 
    1088      Specify the implementation for the ``__init__`` function on a mapped 
    1089      class that has no ``__init__`` of its own.  Defaults to an 
    1090      implementation that assigns \**kwargs for declared 
    1091      fields and relationships to an instance.  If ``None`` is supplied, 
    1092      no __init__ will be provided and construction will fall back to 
    1093      cls.__init__ by way of the normal Python semantics. 
    1094 
    1095    :param class_registry: optional dictionary that will serve as the 
    1096      registry of class names-> mapped classes when string names 
    1097      are used to identify classes inside of :func:`_orm.relationship` 
    1098      and others.  Allows two or more declarative base classes 
    1099      to share the same registry of class names for simplified 
    1100      inter-base relationships. 
    1101 
    1102    :param type_annotation_map: optional dictionary of Python types to 
    1103        SQLAlchemy :class:`_types.TypeEngine` classes or instances.  This 
    1104        is used exclusively by the :class:`_orm.MappedColumn` construct 
    1105        to produce column types based on annotations within the 
    1106        :class:`_orm.Mapped` type. 
    1107 
    1108 
    1109        .. versionadded:: 2.0 
    1110 
    1111        .. seealso:: 
    1112 
    1113            :ref:`orm_declarative_mapped_column_type_map` 
    1114 
    1115    :param metaclass: 
    1116      Defaults to :class:`.DeclarativeMeta`.  A metaclass or __metaclass__ 
    1117      compatible callable to use as the meta type of the generated 
    1118      declarative base class. 
    1119 
    1120    .. seealso:: 
    1121 
    1122        :class:`_orm.registry` 
    1123 
    1124    """ 
    1125 
    1126    return registry( 
    1127        metadata=metadata, 
    1128        class_registry=class_registry, 
    1129        constructor=constructor, 
    1130        type_annotation_map=type_annotation_map, 
    1131    ).generate_base( 
    1132        mapper=mapper, 
    1133        cls=cls, 
    1134        name=name, 
    1135        metaclass=metaclass, 
    1136    ) 
    1137 
    1138 
    1139class registry(EventTarget): 
    1140    """Generalized registry for mapping classes. 
    1141 
    1142    The :class:`_orm.registry` serves as the basis for maintaining a collection 
    1143    of mappings, and provides configurational hooks used to map classes. 
    1144 
    1145    The three general kinds of mappings supported are Declarative Base, 
    1146    Declarative Decorator, and Imperative Mapping.   All of these mapping 
    1147    styles may be used interchangeably: 
    1148 
    1149    * :meth:`_orm.registry.generate_base` returns a new declarative base 
    1150      class, and is the underlying implementation of the 
    1151      :func:`_orm.declarative_base` function. 
    1152 
    1153    * :meth:`_orm.registry.mapped` provides a class decorator that will 
    1154      apply declarative mapping to a class without the use of a declarative 
    1155      base class. 
    1156 
    1157    * :meth:`_orm.registry.map_imperatively` will produce a 
    1158      :class:`_orm.Mapper` for a class without scanning the class for 
    1159      declarative class attributes. This method suits the use case historically 
    1160      provided by the ``sqlalchemy.orm.mapper()`` classical mapping function, 
    1161      which is removed as of SQLAlchemy 2.0. 
    1162 
    1163    .. versionadded:: 1.4 
    1164 
    1165    .. seealso:: 
    1166 
    1167        :ref:`orm_mapping_classes_toplevel` - overview of class mapping 
    1168        styles. 
    1169 
    1170    """ 
    1171 
    1172    _class_registry: clsregistry._ClsRegistryType 
    1173    _managers: weakref.WeakKeyDictionary[ClassManager[Any], Literal[True]] 
    1174    metadata: MetaData 
    1175    constructor: CallableReference[Callable[..., None]] 
    1176    type_annotation_map: _MutableTypeAnnotationMapType 
    1177    _dependents: Set[_RegistryType] 
    1178    _dependencies: Set[_RegistryType] 
    1179    _new_mappers: bool 
    1180    dispatch: dispatcher["registry"] 
    1181 
    1182    def __init__( 
    1183        self, 
    1184        *, 
    1185        metadata: Optional[MetaData] = None, 
    1186        class_registry: Optional[clsregistry._ClsRegistryType] = None, 
    1187        type_annotation_map: Optional[_TypeAnnotationMapType] = None, 
    1188        constructor: Callable[..., None] = _declarative_constructor, 
    1189    ): 
    1190        r"""Construct a new :class:`_orm.registry` 
    1191 
    1192        :param metadata: 
    1193          An optional :class:`_schema.MetaData` instance.  All 
    1194          :class:`_schema.Table` objects generated using declarative 
    1195          table mapping will make use of this :class:`_schema.MetaData` 
    1196          collection.  If this argument is left at its default of ``None``, 
    1197          a blank :class:`_schema.MetaData` collection is created. 
    1198 
    1199        :param constructor: 
    1200          Specify the implementation for the ``__init__`` function on a mapped 
    1201          class that has no ``__init__`` of its own.  Defaults to an 
    1202          implementation that assigns \**kwargs for declared 
    1203          fields and relationships to an instance.  If ``None`` is supplied, 
    1204          no __init__ will be provided and construction will fall back to 
    1205          cls.__init__ by way of the normal Python semantics. 
    1206 
    1207        :param class_registry: optional dictionary that will serve as the 
    1208          registry of class names-> mapped classes when string names 
    1209          are used to identify classes inside of :func:`_orm.relationship` 
    1210          and others.  Allows two or more declarative base classes 
    1211          to share the same registry of class names for simplified 
    1212          inter-base relationships. 
    1213 
    1214        :param type_annotation_map: optional dictionary of Python types to 
    1215          SQLAlchemy :class:`_types.TypeEngine` classes or instances. 
    1216          The provided dict will update the default type mapping.  This 
    1217          is used exclusively by the :class:`_orm.MappedColumn` construct 
    1218          to produce column types based on annotations within the 
    1219          :class:`_orm.Mapped` type. 
    1220 
    1221          .. versionadded:: 2.0 
    1222 
    1223          .. seealso:: 
    1224 
    1225              :ref:`orm_declarative_mapped_column_type_map` 
    1226 
    1227 
    1228        """ 
    1229        lcl_metadata = metadata or MetaData() 
    1230 
    1231        if class_registry is None: 
    1232            class_registry = weakref.WeakValueDictionary() 
    1233 
    1234        self._class_registry = class_registry 
    1235        self._managers = weakref.WeakKeyDictionary() 
    1236        self.metadata = lcl_metadata 
    1237        self.constructor = constructor 
    1238        self.type_annotation_map = {} 
    1239        if type_annotation_map is not None: 
    1240            self.update_type_annotation_map(type_annotation_map) 
    1241        self._dependents = set() 
    1242        self._dependencies = set() 
    1243 
    1244        self._new_mappers = False 
    1245 
    1246        with mapperlib._CONFIGURE_MUTEX: 
    1247            mapperlib._mapper_registries[self] = True 
    1248 
    1249    def update_type_annotation_map( 
    1250        self, 
    1251        type_annotation_map: _TypeAnnotationMapType, 
    1252    ) -> None: 
    1253        """update the :paramref:`_orm.registry.type_annotation_map` with new 
    1254        values.""" 
    1255 
    1256        self.type_annotation_map.update( 
    1257            { 
    1258                de_optionalize_union_types(typ): sqltype 
    1259                for typ, sqltype in type_annotation_map.items() 
    1260            } 
    1261        ) 
    1262 
    1263    def _resolve_type_with_events( 
    1264        self, 
    1265        cls: Any, 
    1266        key: str, 
    1267        raw_annotation: _MatchedOnType, 
    1268        extracted_type: _MatchedOnType, 
    1269        *, 
    1270        raw_pep_593_type: Optional[GenericProtocol[Any]] = None, 
    1271        pep_593_resolved_argument: Optional[_MatchedOnType] = None, 
    1272        raw_pep_695_type: Optional[TypeAliasType] = None, 
    1273        pep_695_resolved_value: Optional[_MatchedOnType] = None, 
    1274    ) -> Optional[sqltypes.TypeEngine[Any]]: 
    1275        """Resolve type with event support for custom type mapping. 
    1276 
    1277        This method fires the resolve_type_annotation event first to allow 
    1278        custom resolution, then falls back to normal resolution. 
    1279 
    1280        """ 
    1281 
    1282        if self.dispatch.resolve_type_annotation: 
    1283            type_resolve = TypeResolve( 
    1284                self, 
    1285                cls, 
    1286                key, 
    1287                raw_annotation, 
    1288                ( 
    1289                    pep_593_resolved_argument 
    1290                    if pep_593_resolved_argument is not None 
    1291                    else ( 
    1292                        pep_695_resolved_value 
    1293                        if pep_695_resolved_value is not None 
    1294                        else extracted_type 
    1295                    ) 
    1296                ), 
    1297                raw_pep_593_type, 
    1298                pep_593_resolved_argument, 
    1299                raw_pep_695_type, 
    1300                pep_695_resolved_value, 
    1301            ) 
    1302 
    1303            for fn in self.dispatch.resolve_type_annotation: 
    1304                result = fn(type_resolve) 
    1305                if result is not None: 
    1306                    return sqltypes.to_instance(result)  # type: ignore[no-any-return] # noqa: E501 
    1307 
    1308        if raw_pep_695_type is not None: 
    1309            sqltype = self._resolve_type(raw_pep_695_type) 
    1310            if sqltype is not None: 
    1311                return sqltype 
    1312 
    1313        sqltype = self._resolve_type(extracted_type) 
    1314        if sqltype is not None: 
    1315            return sqltype 
    1316 
    1317        if pep_593_resolved_argument is not None: 
    1318            sqltype = self._resolve_type(pep_593_resolved_argument) 
    1319 
    1320        return sqltype 
    1321 
    1322    def _resolve_type( 
    1323        self, python_type: _MatchedOnType 
    1324    ) -> Optional[sqltypes.TypeEngine[Any]]: 
    1325        python_type_type: Type[Any] 
    1326        search: Iterable[Tuple[_MatchedOnType, Type[Any]]] 
    1327 
    1328        if is_generic(python_type): 
    1329            if is_literal(python_type): 
    1330                python_type_type = python_type  # type: ignore[assignment] 
    1331 
    1332                search = ( 
    1333                    (python_type, python_type_type), 
    1334                    *((lt, python_type_type) for lt in LITERAL_TYPES), 
    1335                ) 
    1336            else: 
    1337                python_type_type = python_type.__origin__ 
    1338                search = ((python_type, python_type_type),) 
    1339        elif isinstance(python_type, type): 
    1340            python_type_type = python_type 
    1341            search = ((pt, pt) for pt in python_type_type.__mro__) 
    1342        else: 
    1343            python_type_type = python_type  # type: ignore[assignment] 
    1344            search = ((python_type, python_type_type),) 
    1345 
    1346        for pt, flattened in search: 
    1347            # we search through full __mro__ for types.  however... 
    1348            sql_type = self.type_annotation_map.get(pt) 
    1349            if sql_type is None: 
    1350                sql_type = sqltypes._type_map_get(pt)  # type: ignore  # noqa: E501 
    1351 
    1352            if sql_type is not None: 
    1353                sql_type_inst = sqltypes.to_instance(sql_type) 
    1354 
    1355                # ... this additional step will reject most 
    1356                # type -> supertype matches, such as if we had 
    1357                # a MyInt(int) subclass.  note also we pass NewType() 
    1358                # here directly; these always have to be in the 
    1359                # type_annotation_map to be useful 
    1360                resolved_sql_type = sql_type_inst._resolve_for_python_type( 
    1361                    python_type_type, 
    1362                    pt, 
    1363                    flattened, 
    1364                ) 
    1365                if resolved_sql_type is not None: 
    1366                    return resolved_sql_type 
    1367 
    1368        return None 
    1369 
    1370    @property 
    1371    def mappers(self) -> FrozenSet[Mapper[Any]]: 
    1372        """read only collection of all :class:`_orm.Mapper` objects.""" 
    1373 
    1374        return frozenset(manager.mapper for manager in self._managers) 
    1375 
    1376    def _set_depends_on(self, registry: RegistryType) -> None: 
    1377        if registry is self: 
    1378            return 
    1379        registry._dependents.add(self) 
    1380        self._dependencies.add(registry) 
    1381 
    1382    def _flag_new_mapper(self, mapper: Mapper[Any]) -> None: 
    1383        mapper._ready_for_configure = True 
    1384        if self._new_mappers: 
    1385            return 
    1386 
    1387        for reg in self._recurse_with_dependents({self}): 
    1388            reg._new_mappers = True 
    1389 
    1390    @classmethod 
    1391    def _recurse_with_dependents( 
    1392        cls, registries: Set[RegistryType] 
    1393    ) -> Iterator[RegistryType]: 
    1394        todo = registries 
    1395        done = set() 
    1396        while todo: 
    1397            reg = todo.pop() 
    1398            done.add(reg) 
    1399 
    1400            # if yielding would remove dependents, make sure we have 
    1401            # them before 
    1402            todo.update(reg._dependents.difference(done)) 
    1403            yield reg 
    1404 
    1405            # if yielding would add dependents, make sure we have them 
    1406            # after 
    1407            todo.update(reg._dependents.difference(done)) 
    1408 
    1409    @classmethod 
    1410    def _recurse_with_dependencies( 
    1411        cls, registries: Set[RegistryType] 
    1412    ) -> Iterator[RegistryType]: 
    1413        todo = registries 
    1414        done = set() 
    1415        while todo: 
    1416            reg = todo.pop() 
    1417            done.add(reg) 
    1418 
    1419            # if yielding would remove dependencies, make sure we have 
    1420            # them before 
    1421            todo.update(reg._dependencies.difference(done)) 
    1422 
    1423            yield reg 
    1424 
    1425            # if yielding would remove dependencies, make sure we have 
    1426            # them before 
    1427            todo.update(reg._dependencies.difference(done)) 
    1428 
    1429    def _mappers_to_configure(self) -> Iterator[Mapper[Any]]: 
    1430        return ( 
    1431            manager.mapper 
    1432            for manager in list(self._managers) 
    1433            if manager.is_mapped 
    1434            and not manager.mapper.configured 
    1435            and manager.mapper._ready_for_configure 
    1436        ) 
    1437 
    1438    def _dispose_cls(self, cls: Type[_O]) -> None: 
    1439        clsregistry._remove_class(cls.__name__, cls, self._class_registry) 
    1440 
    1441    def _add_manager(self, manager: ClassManager[Any]) -> None: 
    1442        self._managers[manager] = True 
    1443        if manager.is_mapped: 
    1444            raise exc.ArgumentError( 
    1445                "Class '%s' already has a primary mapper defined. " 
    1446                % manager.class_ 
    1447            ) 
    1448        assert manager.registry is None 
    1449        manager.registry = self 
    1450 
    1451    def configure(self, cascade: bool = False) -> None: 
    1452        """Configure all as-yet unconfigured mappers in this 
    1453        :class:`_orm.registry`. 
    1454 
    1455        The configure step is used to reconcile and initialize the 
    1456        :func:`_orm.relationship` linkages between mapped classes, as well as 
    1457        to invoke configuration events such as the 
    1458        :meth:`_orm.MapperEvents.before_configured` and 
    1459        :meth:`_orm.MapperEvents.after_configured`, which may be used by ORM 
    1460        extensions or user-defined extension hooks. 
    1461 
    1462        If one or more mappers in this registry contain 
    1463        :func:`_orm.relationship` constructs that refer to mapped classes in 
    1464        other registries, this registry is said to be *dependent* on those 
    1465        registries. In order to configure those dependent registries 
    1466        automatically, the :paramref:`_orm.registry.configure.cascade` flag 
    1467        should be set to ``True``. Otherwise, if they are not configured, an 
    1468        exception will be raised.  The rationale behind this behavior is to 
    1469        allow an application to programmatically invoke configuration of 
    1470        registries while controlling whether or not the process implicitly 
    1471        reaches other registries. 
    1472 
    1473        As an alternative to invoking :meth:`_orm.registry.configure`, the ORM 
    1474        function :func:`_orm.configure_mappers` function may be used to ensure 
    1475        configuration is complete for all :class:`_orm.registry` objects in 
    1476        memory. This is generally simpler to use and also predates the usage of 
    1477        :class:`_orm.registry` objects overall. However, this function will 
    1478        impact all mappings throughout the running Python process and may be 
    1479        more memory/time consuming for an application that has many registries 
    1480        in use for different purposes that may not be needed immediately. 
    1481 
    1482        .. seealso:: 
    1483 
    1484            :func:`_orm.configure_mappers` 
    1485 
    1486 
    1487        .. versionadded:: 1.4.0b2 
    1488 
    1489        """ 
    1490        mapperlib._configure_registries({self}, cascade=cascade) 
    1491 
    1492    def dispose(self, cascade: bool = False) -> None: 
    1493        """Dispose of all mappers in this :class:`_orm.registry`. 
    1494 
    1495        After invocation, all the classes that were mapped within this registry 
    1496        will no longer have class instrumentation associated with them. This 
    1497        method is the per-:class:`_orm.registry` analogue to the 
    1498        application-wide :func:`_orm.clear_mappers` function. 
    1499 
    1500        If this registry contains mappers that are dependencies of other 
    1501        registries, typically via :func:`_orm.relationship` links, then those 
    1502        registries must be disposed as well. When such registries exist in 
    1503        relation to this one, their :meth:`_orm.registry.dispose` method will 
    1504        also be called, if the :paramref:`_orm.registry.dispose.cascade` flag 
    1505        is set to ``True``; otherwise, an error is raised if those registries 
    1506        were not already disposed. 
    1507 
    1508        .. versionadded:: 1.4.0b2 
    1509 
    1510        .. seealso:: 
    1511 
    1512            :func:`_orm.clear_mappers` 
    1513 
    1514        """ 
    1515 
    1516        mapperlib._dispose_registries({self}, cascade=cascade) 
    1517 
    1518    def _dispose_manager_and_mapper(self, manager: ClassManager[Any]) -> None: 
    1519        if "mapper" in manager.__dict__: 
    1520            mapper = manager.mapper 
    1521 
    1522            mapper._set_dispose_flags() 
    1523 
    1524        class_ = manager.class_ 
    1525        self._dispose_cls(class_) 
    1526        instrumentation._instrumentation_factory.unregister(class_) 
    1527 
    1528    def generate_base( 
    1529        self, 
    1530        mapper: Optional[Callable[..., Mapper[Any]]] = None, 
    1531        cls: Type[Any] = object, 
    1532        name: str = "Base", 
    1533        metaclass: Type[Any] = DeclarativeMeta, 
    1534    ) -> Any: 
    1535        """Generate a declarative base class. 
    1536 
    1537        Classes that inherit from the returned class object will be 
    1538        automatically mapped using declarative mapping. 
    1539 
    1540        E.g.:: 
    1541 
    1542            from sqlalchemy.orm import registry 
    1543 
    1544            mapper_registry = registry() 
    1545 
    1546            Base = mapper_registry.generate_base() 
    1547 
    1548 
    1549            class MyClass(Base): 
    1550                __tablename__ = "my_table" 
    1551                id = Column(Integer, primary_key=True) 
    1552 
    1553        The above dynamically generated class is equivalent to the 
    1554        non-dynamic example below:: 
    1555 
    1556            from sqlalchemy.orm import registry 
    1557            from sqlalchemy.orm.decl_api import DeclarativeMeta 
    1558 
    1559            mapper_registry = registry() 
    1560 
    1561 
    1562            class Base(metaclass=DeclarativeMeta): 
    1563                __abstract__ = True 
    1564                registry = mapper_registry 
    1565                metadata = mapper_registry.metadata 
    1566 
    1567                __init__ = mapper_registry.constructor 
    1568 
    1569        .. versionchanged:: 2.0 Note that the 
    1570           :meth:`_orm.registry.generate_base` method is superseded by the new 
    1571           :class:`_orm.DeclarativeBase` class, which generates a new "base" 
    1572           class using subclassing, rather than return value of a function. 
    1573           This allows an approach that is compatible with :pep:`484` typing 
    1574           tools. 
    1575 
    1576        The :meth:`_orm.registry.generate_base` method provides the 
    1577        implementation for the :func:`_orm.declarative_base` function, which 
    1578        creates the :class:`_orm.registry` and base class all at once. 
    1579 
    1580        See the section :ref:`orm_declarative_mapping` for background and 
    1581        examples. 
    1582 
    1583        :param mapper: 
    1584          An optional callable, defaults to :class:`_orm.Mapper`. 
    1585          This function is used to generate new :class:`_orm.Mapper` objects. 
    1586 
    1587        :param cls: 
    1588          Defaults to :class:`object`. A type to use as the base for the 
    1589          generated declarative base class. May be a class or tuple of classes. 
    1590 
    1591        :param name: 
    1592          Defaults to ``Base``.  The display name for the generated 
    1593          class.  Customizing this is not required, but can improve clarity in 
    1594          tracebacks and debugging. 
    1595 
    1596        :param metaclass: 
    1597          Defaults to :class:`.DeclarativeMeta`.  A metaclass or __metaclass__ 
    1598          compatible callable to use as the meta type of the generated 
    1599          declarative base class. 
    1600 
    1601        .. seealso:: 
    1602 
    1603            :ref:`orm_declarative_mapping` 
    1604 
    1605            :func:`_orm.declarative_base` 
    1606 
    1607        """ 
    1608        metadata = self.metadata 
    1609 
    1610        bases = not isinstance(cls, tuple) and (cls,) or cls 
    1611 
    1612        class_dict: Dict[str, Any] = dict(registry=self, metadata=metadata) 
    1613        if isinstance(cls, type): 
    1614            class_dict["__doc__"] = cls.__doc__ 
    1615 
    1616        if self.constructor is not None: 
    1617            class_dict["__init__"] = self.constructor 
    1618 
    1619        class_dict["__abstract__"] = True 
    1620        if mapper: 
    1621            class_dict["__mapper_cls__"] = mapper 
    1622 
    1623        if hasattr(cls, "__class_getitem__"): 
    1624 
    1625            def __class_getitem__(cls: Type[_T], key: Any) -> Type[_T]: 
    1626                # allow generic classes in py3.9+ 
    1627                return cls 
    1628 
    1629            class_dict["__class_getitem__"] = __class_getitem__ 
    1630 
    1631        return metaclass(name, bases, class_dict) 
    1632 
    1633    @compat_typing.dataclass_transform( 
    1634        field_specifiers=( 
    1635            MappedColumn, 
    1636            RelationshipProperty, 
    1637            Composite, 
    1638            Synonym, 
    1639            mapped_column, 
    1640            relationship, 
    1641            composite, 
    1642            synonym, 
    1643            deferred, 
    1644        ), 
    1645    ) 
    1646    @overload 
    1647    def mapped_as_dataclass(self, __cls: Type[_O], /) -> Type[_O]: ... 
    1648 
    1649    @overload 
    1650    def mapped_as_dataclass( 
    1651        self, 
    1652        __cls: Literal[None] = ..., 
    1653        /, 
    1654        *, 
    1655        init: Union[_NoArg, bool] = ..., 
    1656        repr: Union[_NoArg, bool] = ...,  # noqa: A002 
    1657        eq: Union[_NoArg, bool] = ..., 
    1658        order: Union[_NoArg, bool] = ..., 
    1659        unsafe_hash: Union[_NoArg, bool] = ..., 
    1660        match_args: Union[_NoArg, bool] = ..., 
    1661        kw_only: Union[_NoArg, bool] = ..., 
    1662        dataclass_callable: Union[_NoArg, Callable[..., Type[Any]]] = ..., 
    1663    ) -> Callable[[Type[_O]], Type[_O]]: ... 
    1664 
    1665    def mapped_as_dataclass( 
    1666        self, 
    1667        __cls: Optional[Type[_O]] = None, 
    1668        /, 
    1669        *, 
    1670        init: Union[_NoArg, bool] = _NoArg.NO_ARG, 
    1671        repr: Union[_NoArg, bool] = _NoArg.NO_ARG,  # noqa: A002 
    1672        eq: Union[_NoArg, bool] = _NoArg.NO_ARG, 
    1673        order: Union[_NoArg, bool] = _NoArg.NO_ARG, 
    1674        unsafe_hash: Union[_NoArg, bool] = _NoArg.NO_ARG, 
    1675        match_args: Union[_NoArg, bool] = _NoArg.NO_ARG, 
    1676        kw_only: Union[_NoArg, bool] = _NoArg.NO_ARG, 
    1677        dataclass_callable: Union[ 
    1678            _NoArg, Callable[..., Type[Any]] 
    1679        ] = _NoArg.NO_ARG, 
    1680    ) -> Union[Type[_O], Callable[[Type[_O]], Type[_O]]]: 
    1681        """Class decorator that will apply the Declarative mapping process 
    1682        to a given class, and additionally convert the class to be a 
    1683        Python dataclass. 
    1684 
    1685        .. seealso:: 
    1686 
    1687            :ref:`orm_declarative_native_dataclasses` - complete background 
    1688            on SQLAlchemy native dataclass mapping 
    1689 
    1690            :func:`_orm.mapped_as_dataclass` - functional version that may 
    1691            provide better compatibility with mypy 
    1692 
    1693        .. versionadded:: 2.0 
    1694 
    1695 
    1696        """ 
    1697 
    1698        decorate = mapped_as_dataclass( 
    1699            self, 
    1700            init=init, 
    1701            repr=repr, 
    1702            eq=eq, 
    1703            order=order, 
    1704            unsafe_hash=unsafe_hash, 
    1705            match_args=match_args, 
    1706            kw_only=kw_only, 
    1707            dataclass_callable=dataclass_callable, 
    1708        ) 
    1709 
    1710        if __cls: 
    1711            return decorate(__cls) 
    1712        else: 
    1713            return decorate 
    1714 
    1715    def mapped(self, cls: Type[_O]) -> Type[_O]: 
    1716        """Class decorator that will apply the Declarative mapping process 
    1717        to a given class. 
    1718 
    1719        E.g.:: 
    1720 
    1721            from sqlalchemy.orm import registry 
    1722 
    1723            mapper_registry = registry() 
    1724 
    1725 
    1726            @mapper_registry.mapped 
    1727            class Foo: 
    1728                __tablename__ = "some_table" 
    1729 
    1730                id = Column(Integer, primary_key=True) 
    1731                name = Column(String) 
    1732 
    1733        See the section :ref:`orm_declarative_mapping` for complete 
    1734        details and examples. 
    1735 
    1736        :param cls: class to be mapped. 
    1737 
    1738        :return: the class that was passed. 
    1739 
    1740        .. seealso:: 
    1741 
    1742            :ref:`orm_declarative_mapping` 
    1743 
    1744            :meth:`_orm.registry.generate_base` - generates a base class 
    1745            that will apply Declarative mapping to subclasses automatically 
    1746            using a Python metaclass. 
    1747 
    1748        .. seealso:: 
    1749 
    1750            :meth:`_orm.registry.mapped_as_dataclass` 
    1751 
    1752        """ 
    1753        _ORMClassConfigurator._as_declarative(self, cls, cls.__dict__) 
    1754        return cls 
    1755 
    1756    def as_declarative_base(self, **kw: Any) -> Callable[[Type[_T]], Type[_T]]: 
    1757        """ 
    1758        Class decorator which will invoke 
    1759        :meth:`_orm.registry.generate_base` 
    1760        for a given base class. 
    1761 
    1762        E.g.:: 
    1763 
    1764            from sqlalchemy.orm import registry 
    1765 
    1766            mapper_registry = registry() 
    1767 
    1768 
    1769            @mapper_registry.as_declarative_base() 
    1770            class Base: 
    1771                @declared_attr 
    1772                def __tablename__(cls): 
    1773                    return cls.__name__.lower() 
    1774 
    1775                id = Column(Integer, primary_key=True) 
    1776 
    1777 
    1778            class MyMappedClass(Base): ... 
    1779 
    1780        All keyword arguments passed to 
    1781        :meth:`_orm.registry.as_declarative_base` are passed 
    1782        along to :meth:`_orm.registry.generate_base`. 
    1783 
    1784        """ 
    1785 
    1786        def decorate(cls: Type[_T]) -> Type[_T]: 
    1787            kw["cls"] = cls 
    1788            kw["name"] = cls.__name__ 
    1789            return self.generate_base(**kw)  # type: ignore 
    1790 
    1791        return decorate 
    1792 
    1793    def map_declaratively(self, cls: Type[_O]) -> Mapper[_O]: 
    1794        """Map a class declaratively. 
    1795 
    1796        In this form of mapping, the class is scanned for mapping information, 
    1797        including for columns to be associated with a table, and/or an 
    1798        actual table object. 
    1799 
    1800        Returns the :class:`_orm.Mapper` object. 
    1801 
    1802        E.g.:: 
    1803 
    1804            from sqlalchemy.orm import registry 
    1805 
    1806            mapper_registry = registry() 
    1807 
    1808 
    1809            class Foo: 
    1810                __tablename__ = "some_table" 
    1811 
    1812                id = Column(Integer, primary_key=True) 
    1813                name = Column(String) 
    1814 
    1815 
    1816            mapper = mapper_registry.map_declaratively(Foo) 
    1817 
    1818        This function is more conveniently invoked indirectly via either the 
    1819        :meth:`_orm.registry.mapped` class decorator or by subclassing a 
    1820        declarative metaclass generated from 
    1821        :meth:`_orm.registry.generate_base`. 
    1822 
    1823        See the section :ref:`orm_declarative_mapping` for complete 
    1824        details and examples. 
    1825 
    1826        :param cls: class to be mapped. 
    1827 
    1828        :return: a :class:`_orm.Mapper` object. 
    1829 
    1830        .. seealso:: 
    1831 
    1832            :ref:`orm_declarative_mapping` 
    1833 
    1834            :meth:`_orm.registry.mapped` - more common decorator interface 
    1835            to this function. 
    1836 
    1837            :meth:`_orm.registry.map_imperatively` 
    1838 
    1839        """ 
    1840        _ORMClassConfigurator._as_declarative(self, cls, cls.__dict__) 
    1841        return cls.__mapper__  # type: ignore 
    1842 
    1843    def map_imperatively( 
    1844        self, 
    1845        class_: Type[_O], 
    1846        local_table: Optional[FromClause] = None, 
    1847        **kw: Any, 
    1848    ) -> Mapper[_O]: 
    1849        r"""Map a class imperatively. 
    1850 
    1851        In this form of mapping, the class is not scanned for any mapping 
    1852        information.  Instead, all mapping constructs are passed as 
    1853        arguments. 
    1854 
    1855        This method is intended to be fully equivalent to the now-removed 
    1856        SQLAlchemy ``mapper()`` function, except that it's in terms of 
    1857        a particular registry. 
    1858 
    1859        E.g.:: 
    1860 
    1861            from sqlalchemy.orm import registry 
    1862 
    1863            mapper_registry = registry() 
    1864 
    1865            my_table = Table( 
    1866                "my_table", 
    1867                mapper_registry.metadata, 
    1868                Column("id", Integer, primary_key=True), 
    1869            ) 
    1870 
    1871 
    1872            class MyClass: 
    1873                pass 
    1874 
    1875 
    1876            mapper_registry.map_imperatively(MyClass, my_table) 
    1877 
    1878        See the section :ref:`orm_imperative_mapping` for complete background 
    1879        and usage examples. 
    1880 
    1881        :param class\_: The class to be mapped.  Corresponds to the 
    1882         :paramref:`_orm.Mapper.class_` parameter. 
    1883 
    1884        :param local_table: the :class:`_schema.Table` or other 
    1885         :class:`_sql.FromClause` object that is the subject of the mapping. 
    1886         Corresponds to the 
    1887         :paramref:`_orm.Mapper.local_table` parameter. 
    1888 
    1889        :param \**kw: all other keyword arguments are passed to the 
    1890         :class:`_orm.Mapper` constructor directly. 
    1891 
    1892        .. seealso:: 
    1893 
    1894            :ref:`orm_imperative_mapping` 
    1895 
    1896            :ref:`orm_declarative_mapping` 
    1897 
    1898        """ 
    1899        return _ORMClassConfigurator._mapper(self, class_, local_table, kw) 
    1900 
    1901 
    1902RegistryType = registry 
    1903 
    1904if not TYPE_CHECKING: 
    1905    # allow for runtime type resolution of ``ClassVar[_RegistryType]`` 
    1906    _RegistryType = registry  # noqa 
    1907 
    1908 
    1909class TypeResolve: 
    1910    """Primary argument to the :meth:`.RegistryEvents.resolve_type_annotation` 
    1911    event. 
    1912 
    1913    This object contains all the information needed to resolve a Python 
    1914    type to a SQLAlchemy type.  The :attr:`.TypeResolve.resolved_type` is 
    1915    typically the main type that's resolved.  To resolve an arbitrary 
    1916    Python type against the current type map, the :meth:`.TypeResolve.resolve` 
    1917    method may be used. 
    1918 
    1919    .. versionadded:: 2.1 
    1920 
    1921    """ 
    1922 
    1923    __slots__ = ( 
    1924        "registry", 
    1925        "cls", 
    1926        "key", 
    1927        "raw_type", 
    1928        "resolved_type", 
    1929        "raw_pep_593_type", 
    1930        "raw_pep_695_type", 
    1931        "pep_593_resolved_argument", 
    1932        "pep_695_resolved_value", 
    1933    ) 
    1934 
    1935    cls: Any 
    1936    "The class being processed during declarative mapping" 
    1937 
    1938    registry: "registry" 
    1939    "The :class:`registry` being used" 
    1940 
    1941    key: str 
    1942    "String name of the ORM mapped attribute being processed" 
    1943 
    1944    raw_type: _MatchedOnType 
    1945    """The type annotation object directly from the attribute's annotations. 
    1946 
    1947    It's recommended to look at :attr:`.TypeResolve.resolved_type` or 
    1948    one of :attr:`.TypeResolve.pep_593_resolved_argument` or 
    1949    :attr:`.TypeResolve.pep_695_resolved_value` rather than the raw type, as 
    1950    the raw type will not be de-optionalized. 
    1951 
    1952    """ 
    1953 
    1954    resolved_type: _MatchedOnType 
    1955    """The de-optionalized, "resolved" type after accounting for :pep:`695` 
    1956    and :pep:`593` indirection: 
    1957 
    1958    * If the annotation were a plain Python type or simple alias e.g. 
    1959      ``Mapped[int]``, the resolved_type will be ``int`` 
    1960    * If the annotation refers to a :pep:`695` type that references a 
    1961      plain Python type or simple alias, e.g. ``type MyType = int`` 
    1962      then ``Mapped[MyType]``, the type will refer to the ``__value__`` 
    1963      of the :pep:`695` type, e.g. ``int``, the same as 
    1964      :attr:`.TypeResolve.pep_695_resolved_value`. 
    1965    * If the annotation refers to a :pep:`593` ``Annotated`` object, or 
    1966      a :pep:`695` type alias that in turn refers to a :pep:`593` type, 
    1967      then the type will be the inner type inside of the ``Annotated``, 
    1968      e.g. ``MyType = Annotated[float, mapped_column(...)]`` with 
    1969      ``Mapped[MyType]`` becomes ``float``, the same as 
    1970      :attr:`.TypeResolve.pep_593_resolved_argument`. 
    1971 
    1972    """ 
    1973 
    1974    raw_pep_593_type: Optional[GenericProtocol[Any]] 
    1975    """The de-optionalized :pep:`593` type, if the raw type referred to one. 
    1976 
    1977    This would refer to an ``Annotated`` object. 
    1978 
    1979    """ 
    1980 
    1981    pep_593_resolved_argument: Optional[_MatchedOnType] 
    1982    """The type extracted from a :pep:`593` ``Annotated`` construct, if the 
    1983    type referred to one. 
    1984 
    1985    When present, this type would be the same as the 
    1986    :attr:`.TypeResolve.resolved_type`. 
    1987 
    1988    """ 
    1989 
    1990    raw_pep_695_type: Optional[TypeAliasType] 
    1991    "The de-optionalized :pep:`695` type, if the raw type referred to one." 
    1992 
    1993    pep_695_resolved_value: Optional[_MatchedOnType] 
    1994    """The de-optionalized type referenced by the raw :pep:`695` type, if the 
    1995    raw type referred to one. 
    1996 
    1997    When present, and a :pep:`593` type is not present, this type would be the 
    1998    same as the :attr:`.TypeResolve.resolved_type`. 
    1999 
    2000    """ 
    2001 
    2002    def __init__( 
    2003        self, 
    2004        registry: RegistryType, 
    2005        cls: Any, 
    2006        key: str, 
    2007        raw_type: _MatchedOnType, 
    2008        resolved_type: _MatchedOnType, 
    2009        raw_pep_593_type: Optional[GenericProtocol[Any]], 
    2010        pep_593_resolved_argument: Optional[_MatchedOnType], 
    2011        raw_pep_695_type: Optional[TypeAliasType], 
    2012        pep_695_resolved_value: Optional[_MatchedOnType], 
    2013    ): 
    2014        self.registry = registry 
    2015        self.cls = cls 
    2016        self.key = key 
    2017        self.raw_type = raw_type 
    2018        self.resolved_type = resolved_type 
    2019        self.raw_pep_593_type = raw_pep_593_type 
    2020        self.pep_593_resolved_argument = pep_593_resolved_argument 
    2021        self.raw_pep_695_type = raw_pep_695_type 
    2022        self.pep_695_resolved_value = pep_695_resolved_value 
    2023 
    2024    def resolve( 
    2025        self, python_type: _MatchedOnType 
    2026    ) -> Optional[sqltypes.TypeEngine[Any]]: 
    2027        """Resolve the given python type using the type_annotation_map of 
    2028        the :class:`registry`. 
    2029 
    2030        :param python_type: a Python type (e.g. ``int``, ``str``, etc.)  Any 
    2031         type object that's present in 
    2032         :paramref:`_orm.registry_type_annotation_map` should produce a 
    2033         non-``None`` result. 
    2034        :return: a SQLAlchemy :class:`.TypeEngine` instance 
    2035         (e.g. :class:`.Integer`, 
    2036         :class:`.String`, etc.), or ``None`` to indicate no type could be 
    2037         matched. 
    2038 
    2039        """ 
    2040        return self.registry._resolve_type(python_type) 
    2041 
    2042 
    2043def as_declarative(**kw: Any) -> Callable[[Type[_T]], Type[_T]]: 
    2044    """ 
    2045    Class decorator which will adapt a given class into a 
    2046    :func:`_orm.declarative_base`. 
    2047 
    2048    This function makes use of the :meth:`_orm.registry.as_declarative_base` 
    2049    method, by first creating a :class:`_orm.registry` automatically 
    2050    and then invoking the decorator. 
    2051 
    2052    E.g.:: 
    2053 
    2054        from sqlalchemy.orm import as_declarative 
    2055 
    2056 
    2057        @as_declarative() 
    2058        class Base: 
    2059            @declared_attr 
    2060            def __tablename__(cls): 
    2061                return cls.__name__.lower() 
    2062 
    2063            id = Column(Integer, primary_key=True) 
    2064 
    2065 
    2066        class MyMappedClass(Base): ... 
    2067 
    2068    .. seealso:: 
    2069 
    2070        :meth:`_orm.registry.as_declarative_base` 
    2071 
    2072    """ 
    2073    metadata, class_registry = ( 
    2074        kw.pop("metadata", None), 
    2075        kw.pop("class_registry", None), 
    2076    ) 
    2077 
    2078    return registry( 
    2079        metadata=metadata, class_registry=class_registry 
    2080    ).as_declarative_base(**kw) 
    2081 
    2082 
    2083@compat_typing.dataclass_transform( 
    2084    field_specifiers=( 
    2085        MappedColumn, 
    2086        RelationshipProperty, 
    2087        Composite, 
    2088        Synonym, 
    2089        mapped_column, 
    2090        relationship, 
    2091        composite, 
    2092        synonym, 
    2093        deferred, 
    2094    ), 
    2095) 
    2096def mapped_as_dataclass( 
    2097    registry: RegistryType, 
    2098    /, 
    2099    *, 
    2100    init: Union[_NoArg, bool] = _NoArg.NO_ARG, 
    2101    repr: Union[_NoArg, bool] = _NoArg.NO_ARG,  # noqa: A002 
    2102    eq: Union[_NoArg, bool] = _NoArg.NO_ARG, 
    2103    order: Union[_NoArg, bool] = _NoArg.NO_ARG, 
    2104    unsafe_hash: Union[_NoArg, bool] = _NoArg.NO_ARG, 
    2105    match_args: Union[_NoArg, bool] = _NoArg.NO_ARG, 
    2106    kw_only: Union[_NoArg, bool] = _NoArg.NO_ARG, 
    2107    dataclass_callable: Union[ 
    2108        _NoArg, Callable[..., Type[Any]] 
    2109    ] = _NoArg.NO_ARG, 
    2110) -> Callable[[Type[_O]], Type[_O]]: 
    2111    """Standalone function form of :meth:`_orm.registry.mapped_as_dataclass` 
    2112    which may have better compatibility with mypy. 
    2113 
    2114    The :class:`_orm.registry` is passed as the first argument to the 
    2115    decorator. 
    2116 
    2117    e.g.:: 
    2118 
    2119        from sqlalchemy.orm import Mapped 
    2120        from sqlalchemy.orm import mapped_as_dataclass 
    2121        from sqlalchemy.orm import mapped_column 
    2122        from sqlalchemy.orm import registry 
    2123 
    2124        some_registry = registry() 
    2125 
    2126 
    2127        @mapped_as_dataclass(some_registry) 
    2128        class Relationships: 
    2129            __tablename__ = "relationships" 
    2130 
    2131            entity_id1: Mapped[int] = mapped_column(primary_key=True) 
    2132            entity_id2: Mapped[int] = mapped_column(primary_key=True) 
    2133            level: Mapped[int] = mapped_column(Integer) 
    2134 
    2135    .. versionadded:: 2.0.44 
    2136 
    2137    """ 
    2138 
    2139    def decorate(cls: Type[_O]) -> Type[_O]: 
    2140        _generate_dc_transforms( 
    2141            init=init, 
    2142            repr=repr, 
    2143            eq=eq, 
    2144            order=order, 
    2145            unsafe_hash=unsafe_hash, 
    2146            match_args=match_args, 
    2147            kw_only=kw_only, 
    2148            dataclass_callable=dataclass_callable, 
    2149            cls_=cls, 
    2150        ) 
    2151        _ORMClassConfigurator._as_declarative(registry, cls, cls.__dict__) 
    2152        return cls 
    2153 
    2154    return decorate 
    2155 
    2156 
    2157@inspection._inspects( 
    2158    DeclarativeMeta, DeclarativeBase, DeclarativeAttributeIntercept 
    2159) 
    2160def _inspect_decl_meta(cls: Type[Any]) -> Optional[Mapper[Any]]: 
    2161    mp: Optional[Mapper[Any]] = _inspect_mapped_class(cls) 
    2162    if mp is None: 
    2163        if _DeferredDeclarativeConfig.has_cls(cls): 
    2164            _DeferredDeclarativeConfig.raise_unmapped_for_cls(cls) 
    2165    return mp 
    2166 
    2167 
    2168@compat_typing.dataclass_transform( 
    2169    field_specifiers=( 
    2170        MappedColumn, 
    2171        RelationshipProperty, 
    2172        Composite, 
    2173        Synonym, 
    2174        mapped_column, 
    2175        relationship, 
    2176        composite, 
    2177        synonym, 
    2178        deferred, 
    2179    ), 
    2180) 
    2181@overload 
    2182def unmapped_dataclass(__cls: Type[_O], /) -> Type[_O]: ... 
    2183 
    2184 
    2185@overload 
    2186def unmapped_dataclass( 
    2187    __cls: Literal[None] = ..., 
    2188    /, 
    2189    *, 
    2190    init: Union[_NoArg, bool] = ..., 
    2191    repr: Union[_NoArg, bool] = ...,  # noqa: A002 
    2192    eq: Union[_NoArg, bool] = ..., 
    2193    order: Union[_NoArg, bool] = ..., 
    2194    unsafe_hash: Union[_NoArg, bool] = ..., 
    2195    match_args: Union[_NoArg, bool] = ..., 
    2196    kw_only: Union[_NoArg, bool] = ..., 
    2197    dataclass_callable: Union[_NoArg, Callable[..., Type[Any]]] = ..., 
    2198) -> Callable[[Type[_O]], Type[_O]]: ... 
    2199 
    2200 
    2201def unmapped_dataclass( 
    2202    __cls: Optional[Type[_O]] = None, 
    2203    /, 
    2204    *, 
    2205    init: Union[_NoArg, bool] = _NoArg.NO_ARG, 
    2206    repr: Union[_NoArg, bool] = _NoArg.NO_ARG,  # noqa: A002 
    2207    eq: Union[_NoArg, bool] = _NoArg.NO_ARG, 
    2208    order: Union[_NoArg, bool] = _NoArg.NO_ARG, 
    2209    unsafe_hash: Union[_NoArg, bool] = _NoArg.NO_ARG, 
    2210    match_args: Union[_NoArg, bool] = _NoArg.NO_ARG, 
    2211    kw_only: Union[_NoArg, bool] = _NoArg.NO_ARG, 
    2212    dataclass_callable: Union[ 
    2213        _NoArg, Callable[..., Type[Any]] 
    2214    ] = _NoArg.NO_ARG, 
    2215) -> Union[Type[_O], Callable[[Type[_O]], Type[_O]]]: 
    2216    """Decorator which allows the creation of dataclass-compatible mixins 
    2217    within mapped class hierarchies based on the 
    2218    :func:`_orm.mapped_as_dataclass` decorator. 
    2219 
    2220    Parameters are the same as those of :func:`_orm.mapped_as_dataclass`. 
    2221    The decorator turns the given class into a SQLAlchemy-compatible dataclass 
    2222    in the same way that :func:`_orm.mapped_as_dataclass` does, taking 
    2223    into account :func:`_orm.mapped_column` and other attributes for dataclass- 
    2224    specific directives, but not actually mapping the class. 
    2225 
    2226    To create unmapped dataclass mixins when using a class hierarchy defined 
    2227    by :class:`.DeclarativeBase` and :class:`.MappedAsDataclass`, the 
    2228    :class:`.MappedAsDataclass` class may be subclassed alone for a similar 
    2229    effect. 
    2230 
    2231    .. versionadded:: 2.1 
    2232 
    2233    .. seealso:: 
    2234 
    2235        :ref:`orm_declarative_dc_mixins` - background and example use. 
    2236 
    2237    """ 
    2238 
    2239    def decorate(cls: Type[_O]) -> Type[_O]: 
    2240        _generate_dc_transforms( 
    2241            init=init, 
    2242            repr=repr, 
    2243            eq=eq, 
    2244            order=order, 
    2245            unsafe_hash=unsafe_hash, 
    2246            match_args=match_args, 
    2247            kw_only=kw_only, 
    2248            dataclass_callable=dataclass_callable, 
    2249            cls_=cls, 
    2250        ) 
    2251        _ORMClassConfigurator._as_unmapped_dataclass(cls, cls.__dict__) 
    2252        return cls 
    2253 
    2254    if __cls: 
    2255        return decorate(__cls) 
    2256    else: 
    2257        return decorate