diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2022-09-29 12:56:23 -0400 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2022-10-05 20:35:57 -0400 |
commit | 566cccc8645be99a23811c39d43481d7248628b0 (patch) | |
tree | 15bad7e506967108c0f2e8aec626e8eebd6ff1fc /lib/sqlalchemy/orm/attributes.py | |
parent | 3ab59694dbe04bf967e9af18d1ae49e1c5ea44ed (diff) | |
download | sqlalchemy-566cccc8645be99a23811c39d43481d7248628b0.tar.gz |
reorganize Mapped[] super outside of MapperProperty
We made all the MapperProperty classes a subclass
of Mapped[] to allow declarative mappings to name
Mapped[] on the left side. this was cheating a bit because
MapperProperty is not actually a descriptor, and the mapping
process replaces the object with InstrumentedAttribute at
mapping time, which is the actual Mapped[] descriptor.
But now in I6929f3da6e441cad92285e7309030a9bac4e429d we
are considering making the "cheating" a little more extensive
by putting DynamicMapped / WriteOnlyMapped in Relationship's
hierarchy, which need a flat out "type: ignore" to work.
Instead of pushing more cheats into the core classes, move
out the "Declarative"-facing versions of these classes to be
typing only: Relationship, Composite, Synonym, and MappedSQLExpression
added for ColumnProperty. Keep the internals expressed on the
old names, RelationshipProperty, CompositeProperty, SynonymProperty,
ColumnProprerty, which will remain "pure" with fully correct typing.
then have the typing only endpoints be where the "cheating"
and "type: ignores" have to happen, so that these are more or less
slightly better forms of "Any".
Change-Id: Ied7cc11196c9204da6851f49593d1b1fd2ef8ad8
Diffstat (limited to 'lib/sqlalchemy/orm/attributes.py')
-rw-r--r-- | lib/sqlalchemy/orm/attributes.py | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/lib/sqlalchemy/orm/attributes.py b/lib/sqlalchemy/orm/attributes.py index 119503014..fcc016f54 100644 --- a/lib/sqlalchemy/orm/attributes.py +++ b/lib/sqlalchemy/orm/attributes.py @@ -39,6 +39,7 @@ from . import collections from . import exc as orm_exc from . import interfaces from ._typing import insp_is_aliased_class +from .base import _DeclarativeMapped from .base import ATTR_EMPTY from .base import ATTR_WAS_SET from .base import CALLABLES_OK @@ -95,7 +96,7 @@ if TYPE_CHECKING: from .collections import CollectionAdapter from .dynamic import DynamicAttributeImpl from .interfaces import MapperProperty - from .relationships import Relationship + from .relationships import RelationshipProperty from .state import InstanceState from .util import AliasedInsp from ..event.base import _Dispatch @@ -131,7 +132,7 @@ SelfQueryableAttribute = TypeVar( @inspection._self_inspects class QueryableAttribute( roles.ExpressionElementRole[_T], - interfaces._MappedAttribute[_T], + _DeclarativeMapped[_T], interfaces.InspectionAttr, interfaces.PropComparator[_T], roles.JoinTargetRole, @@ -408,7 +409,7 @@ class QueryableAttribute( self, *clauses: _ColumnExpressionArgument[bool] ) -> interfaces.PropComparator[bool]: if TYPE_CHECKING: - assert isinstance(self.comparator, Relationship.Comparator) + assert isinstance(self.comparator, RelationshipProperty.Comparator) exprs = tuple( coercions.expect(roles.WhereHavingRole, clause) @@ -507,17 +508,24 @@ class InstrumentedAttribute(QueryableAttribute[_T]): __slots__ = () inherit_cache = True + """:meta private:""" - # if not TYPE_CHECKING: + # hack to make __doc__ writeable on instances of + # InstrumentedAttribute, while still keeping classlevel + # __doc__ correct - @property # type: ignore + @util.rw_hybridproperty # type: ignore def __doc__(self) -> Optional[str]: # type: ignore return self._doc - @__doc__.setter - def __doc__(self, value: Optional[str]) -> None: + @__doc__.setter # type: ignore + def __doc__(self, value: Optional[str]) -> None: # type: ignore self._doc = value + @__doc__.classlevel # type: ignore + def __doc__(cls) -> Optional[str]: # type: ignore + return super().__doc__ + def __set__(self, instance: object, value: Any) -> None: self.impl.set( instance_state(instance), instance_dict(instance), value, None @@ -2612,7 +2620,7 @@ def register_descriptor( class_, key, comparator=comparator, parententity=parententity ) - descriptor.__doc__ = doc + descriptor.__doc__ = doc # type: ignore manager.instrument_attribute(key, descriptor) return descriptor |