summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Merickel <michael@merickel.org>2012-04-10 23:20:11 -0500
committerMichael Merickel <michael@merickel.org>2012-04-10 23:20:11 -0500
commit5473f06c9c51ce4bd5f391a240e7b9b278137c53 (patch)
treeb1d2093324b0fb518aaf77213dfef599250acc2d
parent55747c9487422222f963ba843fdbeb3afc2df74e (diff)
downloadpyramid-5473f06c9c51ce4bd5f391a240e7b9b278137c53.tar.gz
pyramid-5473f06c9c51ce4bd5f391a240e7b9b278137c53.tar.bz2
pyramid-5473f06c9c51ce4bd5f391a240e7b9b278137c53.zip
refactored set_property to support multiple properties in the same subclass
-rw-r--r--pyramid/util.py86
1 files changed, 58 insertions, 28 deletions
diff --git a/pyramid/util.py b/pyramid/util.py
index cca1872b7..ff6ac8f4a 100644
--- a/pyramid/util.py
+++ b/pyramid/util.py
@@ -20,6 +20,59 @@ class InstancePropertyMixin(object):
on the class itself.
"""
+ def _make_property(self, callable, name=None, reify=False):
+ """ Convert a callable into one suitable for adding to the
+ instance. This will return a 2-tuple containing the computed
+ (name, property) pair.
+ """
+
+ is_property = isinstance(callable, property)
+ if is_property:
+ fn = callable
+ if name is None:
+ raise ValueError('must specify "name" for a property')
+ if reify:
+ raise ValueError('cannot reify a property')
+ elif name is not None:
+ fn = lambda this: callable(this)
+ fn.__name__ = name
+ fn.__doc__ = callable.__doc__
+ else:
+ name = callable.__name__
+ fn = callable
+ if reify:
+ import pyramid.decorator # avoid circular import
+ fn = pyramid.decorator.reify(fn)
+ elif not is_property:
+ fn = property(fn)
+
+ return name, fn
+
+ def _set_properties(self, properties):
+ """ Create several properties on the instance at once.
+
+ This is a more efficient version of
+ :meth:`pyramid.util.InstancePropertyMixin.set_property` which
+ can accept multiple ``(name, property)`` pairs generated via
+ :meth:`pyramid.util.InstancePropertyMixin._make_property`.
+
+ ``attrs`` is a sequence of 2-tuples *or* a data structure with
+ an ``.items()`` method which returns a sequence of 2-tuples
+ (presumably a dictionary). It will be used used to add several
+ properties to the instance in a manner that is more efficient
+ than simply calling ``set_property`` repeatedly.
+ """
+
+ if hasattr(properties, 'items'):
+ attrs = properties.items()
+ else:
+ attrs = properties
+ attrs = dict(properties)
+
+ parent = self.__class__
+ cls = type(parent.__name__, (parent, object), attrs)
+ self.__class__ = cls
+
def set_property(self, callable, name=None, reify=False):
""" Add a callable or a property descriptor to the instance.
@@ -31,12 +84,11 @@ class InstancePropertyMixin(object):
A property may also be reified via the
:class:`pyramid.decorator.reify` decorator by setting
``reify=True``, allowing the result of the evaluation to be
- cached. Thus the value of the property is only computed once for
- the lifetime of the object.
+ cached. Using this method, the value of the property is only
+ computed once for the lifetime of the object.
``callable`` can either be a callable that accepts the instance
- as
- its single positional parameter, or it can be a property
+ as its single positional parameter, or it can be a property
descriptor.
If the ``callable`` is a property descriptor, the ``name``
@@ -73,30 +125,8 @@ class InstancePropertyMixin(object):
>>> foo.y # notice y keeps the original value
1
"""
-
- is_property = isinstance(callable, property)
- if is_property:
- fn = callable
- if name is None:
- raise ValueError('must specify "name" for a property')
- if reify:
- raise ValueError('cannot reify a property')
- elif name is not None:
- fn = lambda this: callable(this)
- fn.__name__ = name
- fn.__doc__ = callable.__doc__
- else:
- name = callable.__name__
- fn = callable
- if reify:
- import pyramid.decorator
- fn = pyramid.decorator.reify(fn)
- elif not is_property:
- fn = property(fn)
- attrs = { name: fn }
- parent = self.__class__
- cls = type(parent.__name__, (parent, object), attrs)
- self.__class__ = cls
+ prop = self._make_property(callable, name=name, reify=reify)
+ self._set_properties([prop])
class WeakOrderedSet(object):
""" Maintain a set of items.