diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2019-03-26 12:58:42 -0400 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2019-03-26 15:17:48 -0400 |
| commit | 51f81d00dc6103c1dea939513a3437a5ab433e75 (patch) | |
| tree | 5a140a115a5317b827ce34f60506b15b99f4e886 /lib/sqlalchemy/ext/associationproxy.py | |
| parent | 8acbc2624fb4b457e47fab93e6a44a1e37caeddc (diff) | |
| download | sqlalchemy-51f81d00dc6103c1dea939513a3437a5ab433e75.tar.gz | |
Refine ambiguous access for unknown attribute types
Restored instance-level support for plain Python descriptors, e.g.
``@property`` objects, in conjunction with association proxies, in that if
the proxied object is not within ORM scope at all, it gets classified as
"ambiguous" but is proxed directly. For class level access, a basic class
level``__get__()`` now returns the
:class:`.AmbiguousAssociationProxyInstance` directly, rather than raising
its exception, which is the closest approximation to the previous behavior
that returned the :class:`.AssociationProxy` itself that's possible. Also
improved the stringification of these objects to be more descriptive of
current state.
Fixes: #4574
Change-Id: I787a22806b5530c146ae6ee66b588e5b191ae689
Diffstat (limited to 'lib/sqlalchemy/ext/associationproxy.py')
| -rw-r--r-- | lib/sqlalchemy/ext/associationproxy.py | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/lib/sqlalchemy/ext/associationproxy.py b/lib/sqlalchemy/ext/associationproxy.py index ea3b8fade..b8672e739 100644 --- a/lib/sqlalchemy/ext/associationproxy.py +++ b/lib/sqlalchemy/ext/associationproxy.py @@ -295,6 +295,12 @@ class AssociationProxy(interfaces.InspectionAttrInfo): return getter, setter + def __repr__(self): + return "AssociationProxy(%r, %r)" % ( + self.target_collection, + self.value_attr, + ) + class AssociationProxyInstance(object): """A per-class object that serves class- and object-specific results. @@ -385,7 +391,11 @@ class AssociationProxyInstance(object): ) attr = getattr(target_class, value_attr) - if attr._is_internal_proxy and not hasattr(attr, "impl"): + if ( + not hasattr(attr, "_is_internal_proxy") + or attr._is_internal_proxy + and not hasattr(attr, "impl") + ): return AmbiguousAssociationProxyInstance( parent, owning_class, target_class, value_attr ) @@ -724,6 +734,9 @@ class AssociationProxyInstance(object): criterion=criterion, is_has=True, **kwargs ) + def __repr__(self): + return "%s(%r)" % (self.__class__.__name__, self.parent) + class AmbiguousAssociationProxyInstance(AssociationProxyInstance): """an :class:`.AssociationProxyInstance` where we cannot determine @@ -748,10 +761,16 @@ class AmbiguousAssociationProxyInstance(AssociationProxyInstance): def get(self, obj): if obj is None: - self._ambiguous() + return self else: return super(AmbiguousAssociationProxyInstance, self).get(obj) + def __eq__(self, obj): + self._ambiguous() + + def __ne__(self, obj): + self._ambiguous() + def any(self, criterion=None, **kwargs): self._ambiguous() |
