Using zope.location
¶
Location
¶
The Location
base class is a mix-in that defines __parent__
and
__name__
attributes.
Usage within an Object field:
>>> 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', <type 'unicode'>, '__name__')], 'location')
inside()
¶
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
LocationProxy
¶
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
LocationInterator()
¶
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)
>>> next(iter) is o3
True
>>> next(iter) is o2
True
>>> next(iter) is o1
True
>>> next(iter)
Traceback (most recent call last):
...
StopIteration
located()
¶
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