From a7a6d7568546dcc88d836653cce8e69916f1e442 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 1 May 2009 08:02:55 +0000 Subject: - The ``repoze.bfg.location.LocationProxy`` class and the ``repoze.bfg.location.ClassAndInstanceDescr`` class have both been removed in order to be able to eventually shed a dependency on ``zope.proxy``. Neither of these classes was ever an API. - In all previous releases, the ``repoze.bfg.location.locate`` function worked like so: if a model did not explicitly provide the ``repoze.bfg.interfaces.ILocation`` interface, ``locate`` returned a ``LocationProxy`` object representing ``model`` with its ``__parent__`` attribute assigned to ``parent`` and a ``__name__`` attribute assigned to ``__name__``. In this release, the ``repoze.bfg.location.locate`` function simply jams the ``__name__`` and ``__parent__`` attributes on to the supplied model unconditionally, no matter if the object implements ILocation or not, and it never returns a proxy. This was done because the LocationProxy behavior has now moved into an add-on package (``repoze.bfg.traversalwrapper``), in order to eventually be able to shed a dependency on ``zope.proxy``. - In all previous releases, by default, if traversal was used (as opposed to URL-dispatch), and the root object supplied the``repoze.bfg.interfaces.ILocation`` interface, but the children returned via its ``__getitem__`` returned an object that did not implement the same interface, :mod:`repoze.bfg` provided some implicit help during traversal. This traversal feature wrapped subobjects from the root (and thereafter) that did not implement ``ILocation`` in proxies which automatically provided them with a ``__name__`` and ``__parent__`` attribute based on the name being traversed and the previous object traversed. This feature has now been removed from the base ``repoze.bfg`` package for purposes of eventually shedding a dependency on ``zope.proxy``. In order to re-enable the wrapper behavior for older applications which cannot be changed, register the "traversalwrapper" ``ModelGraphTraverser`` as the traversal policy, rather than the default ``ModelGraphTraverser``. To use this feature, you will need to install the ``repoze.bfg.traversalwrapper`` package (an add-on package, available at http://svn.repoze.org/repoze.bfg.traversalwrapper) Then change your application's ``configure.zcml`` to include the following stanza: When this ITraverserFactory is used instead of the default, no object in the graph (even the root object) must supply a ``__name__`` or ``__parent__`` attribute. Even if subobjects returned from the root *do* implement the ILocation interface, these will still be wrapped in proxies that override the object's "real" ``__parent__`` and ``__name__`` attributes. See also changes to the "Models" chapter of the documentation (in the "Location-Aware Model Instances") section. --- repoze/bfg/location.py | 77 ++++++-------------------------------------------- 1 file changed, 9 insertions(+), 68 deletions(-) (limited to 'repoze/bfg/location.py') diff --git a/repoze/bfg/location.py b/repoze/bfg/location.py index ed7d2ad1f..7e9d622c2 100644 --- a/repoze/bfg/location.py +++ b/repoze/bfg/location.py @@ -12,15 +12,11 @@ # ############################################################################## -"""Location support borrowed from ``zope.location``, but without -``zope.security`` support, which is not used by ``repoze.bfg`` +"""Location support loosely based from ``zope.location``, but without +``zope.security`` support or proxy support, neither of which is used +by ``repoze.bfg`` """ -import zope.interface -from repoze.bfg.interfaces import ILocation -from zope.proxy import ProxyBase, getProxiedObject, non_overridable -from zope.proxy.decorator import DecoratorSpecificationDescriptor - def inside(model1, model2): """Is ``model1`` 'inside' ``model2``? Return ``True`` if so, else ``False``. @@ -38,25 +34,13 @@ def inside(model1, model2): def locate(model, parent, name=None): """ - If ``model`` explicitly provides the - ``repoze.bfg.interfaces.ILocation`` interface, directly set - ``model`` 's ``__parent__`` attribute to the ``parent`` object - (also a model), and its ``__name__`` to the supplied ``name`` - argument, and return the model. - - If ``model`` does *not* explicitly provide the - ``repoze.bfg.interfaces.ILocation`` interface, return a - ``LocationProxy`` object representing ``model`` with its - ``__parent__`` attribute assigned to ``parent`` and a ``__name__`` - attribute assigned to ``__name__``. A ``LocationProxy`` object is - an unpickleable proxy that can 'stand in' for arbitrary object - instances. + Directly set ``model`` 's ``__parent__`` attribute to the + ``parent`` object (also a model), and its ``__name__`` to the + supplied ``name`` argument, and return the model. """ - if ILocation.providedBy(model): - model.__parent__ = parent - model.__name__ = name - return model - return LocationProxy(model, parent, name) + model.__parent__ = parent + model.__name__ = name + return model def lineage(model): """ @@ -83,46 +67,3 @@ def lineage(model): yield model model = getattr(model, '__parent__', None) -class ClassAndInstanceDescr(object): - - def __init__(self, *args): - self.funcs = args - - def __get__(self, inst, cls): - if inst is None: - return self.funcs[1](cls) - return self.funcs[0](inst) - -class LocationProxy(ProxyBase): - """Location-object proxy - - This is a non-picklable proxy that can be put around objects that - don't implement `ILocation`. - """ - - zope.interface.implements(ILocation) - - __slots__ = '__parent__', '__name__' - __safe_for_unpickling__ = True - - def __new__(self, ob, container=None, name=None): - return ProxyBase.__new__(self, ob) - - def __init__(self, ob, container=None, name=None): - ProxyBase.__init__(self, ob) - self.__parent__ = container - self.__name__ = name - - @non_overridable - def __reduce__(self, proto=None): - raise TypeError("Not picklable") - - __doc__ = ClassAndInstanceDescr( - lambda inst: getProxiedObject(inst).__doc__, - lambda cls, __doc__ = __doc__: __doc__, - ) - - __reduce_ex__ = __reduce__ - - __providedBy__ = DecoratorSpecificationDescriptor() - -- cgit v1.2.3