diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2010-12-28 17:50:36 -0500 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2010-12-28 17:50:36 -0500 |
| commit | 4f8f6b3989327398c048fa55bc2ed8f26fb022bd (patch) | |
| tree | eb197ce78f67622e3c73d3565e3d946ba6bf8d2c /lib/sqlalchemy/orm | |
| parent | 7f8ca36036d9ab1f8c06ada19a2cd69349864a45 (diff) | |
| download | sqlalchemy-4f8f6b3989327398c048fa55bc2ed8f26fb022bd.tar.gz | |
- simplified the descriptor system to no longer use the hybrid extension, instead presenting
the Proxy(QueryableAttribute) object as the public facing interface. This simplifies
the descriptor system and will allow straightforward integration with attribute events.
Diffstat (limited to 'lib/sqlalchemy/orm')
| -rw-r--r-- | lib/sqlalchemy/orm/attributes.py | 26 | ||||
| -rw-r--r-- | lib/sqlalchemy/orm/descriptor_props.py | 40 | ||||
| -rw-r--r-- | lib/sqlalchemy/orm/util.py | 9 |
3 files changed, 34 insertions, 41 deletions
diff --git a/lib/sqlalchemy/orm/attributes.py b/lib/sqlalchemy/orm/attributes.py index e2d2c559b..d6dc10ad4 100644 --- a/lib/sqlalchemy/orm/attributes.py +++ b/lib/sqlalchemy/orm/attributes.py @@ -145,16 +145,25 @@ def create_proxied_attribute(descriptor): Returns a new QueryableAttribute type that delegates descriptor behavior and getattr() to the given descriptor. """ - + + # TODO: can move this to descriptor_props if the need for this + # function is removed from ext/hybrid.py + class Proxy(QueryableAttribute): - """A combination of InsturmentedAttribute and a regular descriptor.""" + """Presents the :class:`.QueryableAttribute` interface as a + proxy on top of a Python descriptor / :class:`.PropComparator` + combination. + + """ - def __init__(self, class_, key, descriptor, comparator, adapter=None): + def __init__(self, class_, key, descriptor, comparator, + adapter=None, doc=None): self.class_ = class_ self.key = key self.descriptor = descriptor self._comparator = comparator self.adapter = adapter + self.__doc__ = doc @util.memoized_property def comparator(self): @@ -164,11 +173,12 @@ def create_proxied_attribute(descriptor): self._comparator = self._comparator.adapted(self.adapter) return self._comparator - def adapted(self, adapter): - return self.__class__(self.class_, self.key, self.descriptor, - self._comparator, - adapter) - + def __get__(self, instance, owner): + if instance is None: + return self + else: + return self.descriptor.__get__(instance, owner) + def __str__(self): return self.key diff --git a/lib/sqlalchemy/orm/descriptor_props.py b/lib/sqlalchemy/orm/descriptor_props.py index 4c4bc821f..347f9bce9 100644 --- a/lib/sqlalchemy/orm/descriptor_props.py +++ b/lib/sqlalchemy/orm/descriptor_props.py @@ -7,8 +7,7 @@ """Descriptor proprerties are more "auxilliary" properties that exist as configurational elements, but don't participate -as actively in the load/persist ORM loop. They all -build on the "hybrid" extension to produce class descriptors. +as actively in the load/persist ORM loop. """ @@ -22,13 +21,12 @@ properties = util.importlater('sqlalchemy.orm', 'properties') class DescriptorProperty(MapperProperty): """:class:`MapperProperty` which proxies access to a user-defined descriptor.""" - - def instrument_class(self, mapper): - from sqlalchemy.ext import hybrid + doc = None + + def instrument_class(self, mapper): prop = self - # hackety hack hack class _ProxyImpl(object): accepts_scalar_loader = False expire_missing = True @@ -52,39 +50,25 @@ class DescriptorProperty(MapperProperty): delattr(obj, self.name) def fget(obj): return getattr(obj, self.name) - fget.__doc__ = self.doc - descriptor = hybrid.property_( + self.descriptor = property( fget=fget, fset=fset, fdel=fdel, ) - elif isinstance(self.descriptor, property): - descriptor = hybrid.property_( - fget=self.descriptor.fget, - fset=self.descriptor.fset, - fdel=self.descriptor.fdel, - ) - else: - descriptor = hybrid.property_( - fget=self.descriptor.__get__, - fset=self.descriptor.__set__, - fdel=self.descriptor.__delete__, - ) proxy_attr = attributes.\ - create_proxied_attribute(self.descriptor or descriptor)\ + create_proxied_attribute(self.descriptor)\ ( self.parent.class_, self.key, - self.descriptor or descriptor, - lambda: self._comparator_factory(mapper) + self.descriptor, + lambda: self._comparator_factory(mapper), + doc=self.doc ) - def get_comparator(owner): - return util.update_wrapper(proxy_attr, descriptor) - descriptor.expr = get_comparator - descriptor.impl = _ProxyImpl(self.key) - mapper.class_manager.instrument_attribute(self.key, descriptor) + + proxy_attr.impl = _ProxyImpl(self.key) + mapper.class_manager.instrument_attribute(self.key, proxy_attr) class CompositeProperty(DescriptorProperty): diff --git a/lib/sqlalchemy/orm/util.py b/lib/sqlalchemy/orm/util.py index 52e250239..4a8b1713c 100644 --- a/lib/sqlalchemy/orm/util.py +++ b/lib/sqlalchemy/orm/util.py @@ -247,13 +247,12 @@ class AliasedClass(object): 'parentmapper':self.__mapper} ) - def __adapt_prop(self, prop): - existing = getattr(self.__target, prop.key) + def __adapt_prop(self, existing, key): comparator = existing.comparator.adapted(self.__adapt_element) - queryattr = attributes.QueryableAttribute(self, prop.key, + queryattr = attributes.QueryableAttribute(self, key, impl=existing.impl, parententity=self, comparator=comparator) - setattr(self, prop.key, queryattr) + setattr(self, key, queryattr) return queryattr def __getattr__(self, key): @@ -268,7 +267,7 @@ class AliasedClass(object): raise AttributeError(key) if isinstance(attr, attributes.QueryableAttribute): - return self.__adapt_prop(attr.property) + return self.__adapt_prop(attr, key) elif hasattr(attr, 'func_code'): is_method = getattr(self.__target, key, None) if is_method and is_method.im_self is not None: |
