Skip to content

Instantly share code, notes, and snippets.

@agriffis
Last active December 14, 2015 07:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save agriffis/5054133 to your computer and use it in GitHub Desktop.
Save agriffis/5054133 to your computer and use it in GitHub Desktop.
URL tree walkers, recursive and non-recursive.
def walk_url_tree(urls):
"""
Generator to walk a tree consisting of RegexURLPattern (with callback)
and RegexURLResolver (with nested url_patterns).
Recursive depth-first.
"""
for u in urls:
if hasattr(u, 'url_patterns'):
for u2 in walk_url_tree(u.url_patterns):
yield u2
else:
yield u
def walk_url_tree(urls):
"""
Generator to walk a tree consisting of RegexURLPattern (with callback)
and RegexURLResolver (with nested url_patterns).
Non-recursive breadth-first.
"""
ulist = list(urls)
for u in ulist:
try:
ulist.extend(u.url_patterns)
except AttributeError:
yield u
def walk_url_tree(urls):
"""
Generator to walk a tree consisting of RegexURLPattern (with callback)
and RegexURLResolver (with nested url_patterns).
Non-recursive depth-first in reverse, using a LIFO to avoid
accumulating the entire list.
"""
lifo = list(urls)
while lifo:
u = lifo.pop()
try:
lifo.extend(u.url_patterns)
except AttributeError:
yield u
def walk_url_tree(urls):
"""
Generator to walk a tree consisting of RegexURLPattern (with callback)
and RegexURLResolver (with nested url_patterns).
Non-recursive breadth-first using chain_plus.
"""
it = chain_plus(urls)
for u in it:
try:
it.link(u.url_patterns)
except AttributeError:
yield u
from collections import deque
class chain_plus(object):
"""
Same as itertools.chain() except this can be extended during iteration
by linking more iterables to the end of the chain.
"""
def __init__(self, *iterables):
self._iterators = deque()
self.link(*iterables)
def __iter__(self):
return self
def link(self, *iterables):
self._iterators.extend(iter(i) for i in iterables)
def next(self):
while self._iterators:
try:
return next(self._iterators[0])
except StopIteration:
self._iterators.popleft()
raise StopIteration
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment