def traversePathElement(obj, name, further_path, default=_marker, traversable=None, request=None): """ Traverse a single step *name* relative to the given object. This is used to implement :meth:`zope.traversing.interfaces.ITraversalAPI.traverseName`. :param str name: must be a string. '.' and '..' are treated specially, as well as names starting with '@' or '+'. Otherwise *name* will be treated as a single path segment. :param list further_path: a list of names still to be traversed. This method is allowed to change the contents of *further_path*. :keyword ITraversable traversable: You can explicitly pass in an `~zope.traversing.interfaces.ITraversable` as the *traversable* argument. If you do not, the given object will be adapted to ``ITraversable``. :keyword request: assed in when traversing from presentation code. This allows paths like ``@@foo`` to work. :raises zope.location.interfaces.LocationError: if *path* cannot be found and '*default* was not provided. """ __traceback_info__ = (obj, name) if name == '.': return obj if name == '..': return obj.__parent__ if name and name[:1] in '@+': ns, nm = nsParse(name) if ns: return namespaceLookup(ns, nm, obj, request) else: nm = name if traversable is None: traversable = ITraversable(obj, None) if traversable is None: raise LocationError('No traversable adapter found', obj) try: return traversable.traverse(nm, further_path) except UnicodeEncodeError: # If we're on Python 2, and nm was a unicode string, and the traversable # tried to do an attribute lookup, the nm would have been encoded using the # system encoding (usually ascii). Failure to encode means invalid attribute # name. if default is not _marker: return default raise LocationError(obj, name) except LocationError: if default is not _marker: return default raise
def traversePathElement(obj, name, further_path, default=_marker, traversable=None, request=None): """Traverse a single step 'name' relative to the given object. 'name' must be a string. '.' and '..' are treated specially, as well as names starting with '@' or '+'. Otherwise 'name' will be treated as a single path segment. 'further_path' is a list of names still to be traversed. This method is allowed to change the contents of 'further_path'. You can explicitly pass in an ITraversable as the 'traversable' argument. If you do not, the given object will be adapted to ITraversable. 'request' is passed in when traversing from presentation code. This allows paths like @@foo to work. Raises LocationError if path cannot be found and 'default' was not provided. """ __traceback_info__ = (obj, name) if name == '.': return obj if name == '..': return obj.__parent__ if name and name[:1] in '@+': ns, nm = nsParse(name) if ns: return namespaceLookup(ns, nm, obj, request) else: nm = name if traversable is None: traversable = ITraversable(obj, None) if traversable is None: raise LocationError('No traversable adapter found', obj) try: return traversable.traverse(nm, further_path) except UnicodeEncodeError: # If we're on Python 2, and nm was a unicode string, and the traversable # tried to do an attribute lookup, the nm would have been encoded using the # system encoding (usually ascii). Failure to encode means invalid attribute # name. if default is not _marker: return default raise LocationError(obj, name) except LocationError: if default is not _marker: return default raise
def traversePathElement(obj, name, further_path, default=_marker, traversable=None, request=None): """Traverse a single step 'name' relative to the given object. 'name' must be a string. '.' and '..' are treated specially, as well as names starting with '@' or '+'. Otherwise 'name' will be treated as a single path segment. 'further_path' is a list of names still to be traversed. This method is allowed to change the contents of 'further_path'. You can explicitly pass in an ITraversable as the 'traversable' argument. If you do not, the given object will be adapted to ITraversable. 'request' is passed in when traversing from presentation code. This allows paths like @@foo to work. Raises LocationError if path cannot be found and 'default' was not provided. """ __traceback_info__ = (obj, name) if name == '.': return obj if name == '..': return obj.__parent__ if name and name[:1] in '@+': ns, nm = nsParse(name) if ns: return namespaceLookup(ns, nm, obj, request) else: nm = name if traversable is None: traversable = ITraversable(obj, None) if traversable is None: raise LocationError('No traversable adapter found', obj) try: return traversable.traverse(nm, further_path) except LocationError: if default is not _marker: return default else: raise return obj
def traverse(self, name, remaining): """Acquire a name Let's set up some example data: >>> class testcontent(object): ... zope.interface.implements(ITraversable) ... def traverse(self, name, remaining): ... v = getattr(self, name, None) ... if v is None: ... raise LocationError(self, name) ... return v ... def __repr__(self): ... return 'splat' >>> ob = testcontent() >>> ob.a = 1 >>> ob.__parent__ = testcontent() >>> ob.__parent__.b = 2 >>> ob.__parent__.__parent__ = testcontent() >>> ob.__parent__.__parent__.c = 3 And acquire some names: >>> adapter = acquire(ob) >>> adapter.traverse('a', ()) 1 >>> adapter.traverse('b', ()) 2 >>> adapter.traverse('c', ()) 3 >>> adapter.traverse('d', ()) Traceback (most recent call last): ... LocationError: (splat, 'd') """ i = 0 ob = self.context while i < 200: i += 1 traversable = ITraversable(ob, None) if traversable is not None: try: # ??? what do we do if the path gets bigger? path = [] next = traversable.traverse(name, path) if path: continue except LocationError: pass else: return next ob = getattr(ob, '__parent__', None) if ob is None: raise LocationError(self.context, name) raise ExcessiveDepth(self.context, name)
def traverse(self, name, remaining): """ Acquire a name Let's set up some example data:: >>> @zope.interface.implementer(ITraversable) ... class testcontent(object): ... def traverse(self, name, remaining): ... v = getattr(self, name, None) ... if v is None: ... raise LocationError(self, name) ... return v ... def __repr__(self): ... return 'splat' >>> ob = testcontent() >>> ob.a = 1 >>> ob.__parent__ = testcontent() >>> ob.__parent__.b = 2 >>> ob.__parent__.__parent__ = testcontent() >>> ob.__parent__.__parent__.c = 3 And acquire some names: >>> adapter = acquire(ob) >>> adapter.traverse('a', ()) 1 >>> adapter.traverse('b', ()) 2 >>> adapter.traverse('c', ()) 3 >>> adapter.traverse('d', ()) Traceback (most recent call last): ... LocationError: (splat, 'd') """ i = 0 ob = self.context while i < 200: i += 1 traversable = ITraversable(ob, None) if traversable is not None: try: # ??? what do we do if the path gets bigger? path = [] next = traversable.traverse(name, path) if path: continue except LocationError: pass else: return next ob = getattr(ob, '__parent__', None) if ob is None: raise LocationError(self.context, name) raise ExcessiveDepth(self.context, name)
def traversePathElement(obj, name, further_path, default=_marker, traversable=None, request=None): """ Traverse a single step *name* relative to the given object. This is used to implement :meth:`zope.traversing.interfaces.ITraversalAPI.traverseName`. :param str name: must be a string. '.' and '..' are treated specially, as well as names starting with '@' or '+'. Otherwise *name* will be treated as a single path segment. :param list further_path: a list of names still to be traversed. This method is allowed to change the contents of *further_path*. :keyword ITraversable traversable: You can explicitly pass in an `~zope.traversing.interfaces.ITraversable` as the *traversable* argument. If you do not, the given object will be adapted to ``ITraversable``. :keyword request: assed in when traversing from presentation code. This allows paths like ``@@foo`` to work. :raises zope.location.interfaces.LocationError: if *path* cannot be found and '*default* was not provided. """ __traceback_info__ = (obj, name) if name == '.': return obj if name == '..': return obj.__parent__ if name and name[:1] in '@+': ns, nm = nsParse(name) if ns: return namespaceLookup(ns, nm, obj, request) else: nm = name if traversable is None: traversable = ITraversable(obj, None) if traversable is None: raise LocationError('No traversable adapter found', obj) try: return traversable.traverse(nm, further_path) except UnicodeEncodeError: # If we're on Python 2, and nm was a unicode string, and the traversable # tried to do an attribute lookup, the nm would have been encoded using the # system encoding (usually ascii). Failure to encode means invalid attribute # name. if default is not _marker: return default raise LocationError(obj, name) except LocationError: if default is not _marker: return default raise