Using :mod:`zope.location` ========================== :class:`~zope.location.location.Location` ----------------------------------------- The ``Location`` base class is a mix-in that defines ``__parent__`` and ``__name__`` attributes. Usage within an Object field: .. doctest:: >>> from zope.interface import implementer, Interface >>> from zope.schema import Object >>> from zope.schema.fieldproperty import FieldProperty >>> from zope.location.interfaces import ILocation >>> from zope.location.location import Location >>> class IA(Interface): ... location = Object(schema=ILocation, required=False, default=None) >>> @implementer(IA) ... class A(object): ... location = FieldProperty(IA['location']) >>> a = A() >>> a.location = Location() >>> loc = Location(); loc.__name__ = u'foo' >>> a.location = loc >>> loc = Location(); loc.__name__ = None >>> a.location = loc >>> loc = Location(); loc.__name__ = b'foo' >>> a.location = loc Traceback (most recent call last): ... SchemaNotCorrectlyImplemented: ([WrongType('foo', , '__name__')], 'location') :func:`~zope.location.location.inside` -------------------------------------- The ``inside`` function tells if l1 is inside l2. L1 is inside l2 if l2 is an ancestor of l1. .. doctest:: >>> o1 = Location() >>> o2 = Location(); o2.__parent__ = o1 >>> o3 = Location(); o3.__parent__ = o2 >>> o4 = Location(); o4.__parent__ = o3 >>> from zope.location.location import inside >>> inside(o1, o1) True >>> inside(o2, o1) True >>> inside(o3, o1) True >>> inside(o4, o1) True >>> inside(o1, o4) False >>> inside(o1, None) False :class:`~zope.location.location.LocationProxy` ---------------------------------------------- ``LocationProxy`` is a non-picklable proxy that can be put around objects that don't implement ``ILocation``. .. doctest:: >>> from zope.location.location import LocationProxy >>> l = [1, 2, 3] >>> ILocation.providedBy(l) False >>> p = LocationProxy(l, "Dad", "p") >>> p [1, 2, 3] >>> ILocation.providedBy(p) True >>> p.__parent__ 'Dad' >>> p.__name__ 'p' >>> import pickle >>> p2 = pickle.dumps(p) Traceback (most recent call last): ... TypeError: Not picklable Proxies should get their doc strings from the object they proxy: .. doctest:: >>> p.__doc__ == l.__doc__ True If we get a "located class" somehow, its doc string well be available through proxy as well: .. doctest:: >>> class LocalClass(object): ... """This is class that can be located""" >>> p = LocationProxy(LocalClass) >>> p.__doc__ == LocalClass.__doc__ True :func:`~zope.location.location.LocationInterator` ------------------------------------------------- This function allows us to iterate over object and all its parents. .. doctest:: >>> from zope.location.location import LocationIterator >>> o1 = Location() >>> o2 = Location() >>> o3 = Location() >>> o3.__parent__ = o2 >>> o2.__parent__ = o1 >>> iter = LocationIterator(o3) >>> next(iter) is o3 True >>> next(iter) is o2 True >>> next(iter) is o1 True >>> next(iter) Traceback (most recent call last): ... StopIteration :func:`~zope.location.location.located` --------------------------------------- ``located`` locates an object in another and returns it: .. doctest:: >>> from zope.location.location import located >>> a = Location() >>> parent = Location() >>> a_located = located(a, parent, 'a') >>> a_located is a True >>> a_located.__parent__ is parent True >>> a_located.__name__ 'a' If we locate the object again, nothing special happens: .. doctest:: >>> a_located_2 = located(a_located, parent, 'a') >>> a_located_2 is a_located True If the object does not provide ILocation an adapter can be provided: .. doctest:: >>> import zope.interface >>> import zope.component >>> sm = zope.component.getGlobalSiteManager() >>> sm.registerAdapter(LocationProxy, required=(zope.interface.Interface,)) >>> l = [1, 2, 3] >>> parent = Location() >>> l_located = located(l, parent, 'l') >>> l_located.__parent__ is parent True >>> l_located.__name__ 'l' >>> l_located is l False >>> type(l_located) >>> l_located_2 = located(l_located, parent, 'l') >>> l_located_2 is l_located True When changing the name, we still do not get a different proxied object: .. doctest:: >>> l_located_3 = located(l_located, parent, 'new-name') >>> l_located_3 is l_located_2 True >>> sm.unregisterAdapter(LocationProxy, required=(zope.interface.Interface,)) True