diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2018-08-23 12:40:26 -0400 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2018-08-23 12:47:08 -0400 |
| commit | 626356842d77d4ec6427b3bfc04bdff93d24d246 (patch) | |
| tree | 2f9fbf98d73f3647f814940b9d2116d022052ee8 /lib/sqlalchemy/ext/declarative | |
| parent | 469931514a1517dde82ba56f780c3007c66d5943 (diff) | |
| download | sqlalchemy-626356842d77d4ec6427b3bfc04bdff93d24d246.tar.gz | |
Unwrap Proxy objects when scanning declared_attr
Fixed bug where the declarative scan for attributes would receive the
expression proxy delivered by a hybrid attribute at the class level, and
not the hybrid attribute itself, when receiving the descriptor via the
``@declared_attr`` callable on a subclass of an already-mapped class. This
would lead to an attribute that did not report itself as a hybrid when
viewed within :attr:`.Mapper.all_orm_descriptors`.
Fixes: #4326
Change-Id: I582d03f05c3768b3344f93e3791240e9e69b9d1e
Diffstat (limited to 'lib/sqlalchemy/ext/declarative')
| -rw-r--r-- | lib/sqlalchemy/ext/declarative/base.py | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/lib/sqlalchemy/ext/declarative/base.py b/lib/sqlalchemy/ext/declarative/base.py index 818b92c98..9e15582d6 100644 --- a/lib/sqlalchemy/ext/declarative/base.py +++ b/lib/sqlalchemy/ext/declarative/base.py @@ -11,7 +11,7 @@ from ...orm import mapper, class_mapper, synonym from ...orm.interfaces import MapperProperty from ...orm.properties import ColumnProperty, CompositeProperty from ...orm.attributes import QueryableAttribute -from ...orm.base import _is_mapped_class +from ...orm.base import _is_mapped_class, InspectionAttr from ... import util, exc from ...util import topological from ...sql import expression @@ -287,8 +287,18 @@ class _MapperConfig(object): util.warn_deprecated( "Use of sqlalchemy.util.classproperty on " "declarative classes is deprecated.") - dict_[name] = column_copies[obj] = \ - ret = getattr(cls, name) + # access attribute using normal class access + ret = getattr(cls, name) + + # correct for proxies created from hybrid_property + # or similar. note there is no known case that + # produces nested proxies, so we are only + # looking one level deep right now. + if isinstance(ret, InspectionAttr) and \ + ret._is_internal_proxy: + ret = ret.descriptor + + dict_[name] = column_copies[obj] = ret if isinstance(ret, (Column, MapperProperty)) and \ ret.doc is None: ret.doc = obj.__doc__ |
