diff options
Diffstat (limited to 'lib/sqlalchemy/orm/attributes.py')
-rw-r--r-- | lib/sqlalchemy/orm/attributes.py | 69 |
1 files changed, 24 insertions, 45 deletions
diff --git a/lib/sqlalchemy/orm/attributes.py b/lib/sqlalchemy/orm/attributes.py index 6872dd645..86f950813 100644 --- a/lib/sqlalchemy/orm/attributes.py +++ b/lib/sqlalchemy/orm/attributes.py @@ -130,52 +130,38 @@ class InstrumentedAttribute(QueryableAttribute): return self.impl.get(instance_state(instance), instance_dict(instance)) -class _ProxyImpl(object): - accepts_scalar_loader = False - expire_missing = True - - def __init__(self, key): - self.key = key +def create_proxied_attribute(descriptor): + """Create an QueryableAttribute / user descriptor hybrid. -def proxied_attribute_factory(descriptor): - """Create an InstrumentedAttribute / user descriptor hybrid. - - Returns a new InstrumentedAttribute type that delegates descriptor + Returns a new QueryableAttribute type that delegates descriptor behavior and getattr() to the given descriptor. """ - class Proxy(InstrumentedAttribute): + class Proxy(QueryableAttribute): """A combination of InsturmentedAttribute and a regular descriptor.""" - def __init__(self, key, descriptor, comparator, parententity): + def __init__(self, key, descriptor, comparator, adapter=None): self.key = key - # maintain ProxiedAttribute.user_prop compatability. - self.descriptor = self.user_prop = descriptor + self.descriptor = descriptor self._comparator = comparator - self._parententity = parententity - self.impl = _ProxyImpl(key) - + self.adapter = adapter + @util.memoized_property def comparator(self): if util.callable(self._comparator): self._comparator = self._comparator() + if self.adapter: + self._comparator = self._comparator.adapted(self.adapter) return self._comparator + + def adapted(self, adapter): + return self.__class__(self.key, self.descriptor, + self._comparator, + adapter) - def __get__(self, instance, owner): - """Delegate __get__ to the original descriptor.""" - if instance is None: - descriptor.__get__(instance, owner) - return self - return descriptor.__get__(instance, owner) - - def __set__(self, instance, value): - """Delegate __set__ to the original descriptor.""" - return descriptor.__set__(instance, value) - - def __delete__(self, instance): - """Delegate __delete__ to the original descriptor.""" - return descriptor.__delete__(instance) - + def __str__(self): + return self.key + def __getattr__(self, attribute): """Delegate __getattr__ to the original descriptor and/or comparator.""" @@ -184,12 +170,12 @@ def proxied_attribute_factory(descriptor): return getattr(descriptor, attribute) except AttributeError: try: - return getattr(self._comparator, attribute) + return getattr(self.comparator, attribute) except AttributeError: raise AttributeError( 'Neither %r object nor %r object has an attribute %r' % ( type(descriptor).__name__, - type(self._comparator).__name__, + type(self.comparator).__name__, attribute) ) @@ -1030,15 +1016,12 @@ def has_parent(cls, obj, key, optimistic=False): return manager.has_parent(state, key, optimistic) def register_attribute(class_, key, **kw): - proxy_property = kw.pop('proxy_property', None) - comparator = kw.pop('comparator', None) parententity = kw.pop('parententity', None) doc = kw.pop('doc', None) - register_descriptor(class_, key, proxy_property, + register_descriptor(class_, key, comparator, parententity, doc=doc) - if not proxy_property: - register_attribute_impl(class_, key, **kw) + register_attribute_impl(class_, key, **kw) def register_attribute_impl(class_, key, uselist=False, callable_=None, @@ -1074,15 +1057,11 @@ def register_attribute_impl(class_, key, manager.post_configure_attribute(key) -def register_descriptor(class_, key, proxy_property=None, comparator=None, +def register_descriptor(class_, key, comparator=None, parententity=None, property_=None, doc=None): manager = manager_of_class(class_) - if proxy_property: - proxy_type = proxied_attribute_factory(proxy_property) - descriptor = proxy_type(key, proxy_property, comparator, parententity) - else: - descriptor = InstrumentedAttribute(class_, key, comparator=comparator, + descriptor = InstrumentedAttribute(class_, key, comparator=comparator, parententity=parententity) descriptor.__doc__ = doc |