In Zope3, location are special objects that has a structural location.
The Location base class is a stupid mix-in that defines __parent__ and __name__ attributes.
Usage within an Object field:
>>> from zope.interface import implements, 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) >>> class A(object): ... implements(IA) ... 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__ = 'foo' >>> a.location = loc Traceback (most recent call last): ... WrongContainedType: ([WrongType('foo', <type 'unicode'>, '__name__')], 'location')
The inside function tells if l1 is inside l2. L1 is inside l2 if l2 is an ancestor of l1.
>>> 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
The LocationProxy is a non-picklable proxy that can be put around objects that don't implement ILocation.
>>> 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:
>>> p.__doc__ == l.__doc__ True
If we get a "located class" somehow, its doc string well be available through proxy as well:
>>> class LocalClass(object): ... """This is class that can be located""">>> p = LocationProxy(LocalClass) >>> p.__doc__ == LocalClass.__doc__ True
This function allows us to iterate over object and all its parents.
>>> from zope.location.location import LocationIterator>>> o1 = Location() >>> o2 = Location() >>> o3 = Location() >>> o3.__parent__ = o2 >>> o2.__parent__ = o1>>> iter = LocationIterator(o3) >>> iter.next() is o3 True >>> iter.next() is o2 True >>> iter.next() is o1 True >>> iter.next() Traceback (most recent call last): ... StopIteration
located locates an object in another and returns it:
>>> 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:
>>> 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:
>>> 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) <class 'zope.location.location.LocationProxy'> >>> 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:
>>> 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
Use new zope.copy package for implementing location copying. Thus there's changes in the zope.locaton.pickling module:
- The locationCopy and CopyPersistent was removed in prefer to their equivalents in zope.copy. Deprecated backward-compatibility imports provided.
- The module now provides a zope.copy.interfaces.ICopyHook adapter for ILocation objects that replaces the old CopyPersistent functionality of checking for the need to clone objects based on their location.