summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/ext/declarative
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2018-08-23 12:40:26 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2018-08-23 12:47:08 -0400
commit626356842d77d4ec6427b3bfc04bdff93d24d246 (patch)
tree2f9fbf98d73f3647f814940b9d2116d022052ee8 /lib/sqlalchemy/ext/declarative
parent469931514a1517dde82ba56f780c3007c66d5943 (diff)
downloadsqlalchemy-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.py16
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__