| Index: third_party/cython/src/Cython/Tempita/_looper.py
|
| diff --git a/third_party/cython/src/Cython/Tempita/_looper.py b/third_party/cython/src/Cython/Tempita/_looper.py
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..4010988300ffd12da5dd136f1f173d584261191e
|
| --- /dev/null
|
| +++ b/third_party/cython/src/Cython/Tempita/_looper.py
|
| @@ -0,0 +1,163 @@
|
| +"""
|
| +Helper for looping over sequences, particular in templates.
|
| +
|
| +Often in a loop in a template it's handy to know what's next up,
|
| +previously up, if this is the first or last item in the sequence, etc.
|
| +These can be awkward to manage in a normal Python loop, but using the
|
| +looper you can get a better sense of the context. Use like::
|
| +
|
| + >>> for loop, item in looper(['a', 'b', 'c']):
|
| + ... print loop.number, item
|
| + ... if not loop.last:
|
| + ... print '---'
|
| + 1 a
|
| + ---
|
| + 2 b
|
| + ---
|
| + 3 c
|
| +
|
| +"""
|
| +
|
| +import sys
|
| +from Cython.Tempita.compat3 import basestring_
|
| +
|
| +__all__ = ['looper']
|
| +
|
| +
|
| +class looper(object):
|
| + """
|
| + Helper for looping (particularly in templates)
|
| +
|
| + Use this like::
|
| +
|
| + for loop, item in looper(seq):
|
| + if loop.first:
|
| + ...
|
| + """
|
| +
|
| + def __init__(self, seq):
|
| + self.seq = seq
|
| +
|
| + def __iter__(self):
|
| + return looper_iter(self.seq)
|
| +
|
| + def __repr__(self):
|
| + return '<%s for %r>' % (
|
| + self.__class__.__name__, self.seq)
|
| +
|
| +
|
| +class looper_iter(object):
|
| +
|
| + def __init__(self, seq):
|
| + self.seq = list(seq)
|
| + self.pos = 0
|
| +
|
| + def __iter__(self):
|
| + return self
|
| +
|
| + def __next__(self):
|
| + if self.pos >= len(self.seq):
|
| + raise StopIteration
|
| + result = loop_pos(self.seq, self.pos), self.seq[self.pos]
|
| + self.pos += 1
|
| + return result
|
| +
|
| + if sys.version < "3":
|
| + next = __next__
|
| +
|
| +
|
| +class loop_pos(object):
|
| +
|
| + def __init__(self, seq, pos):
|
| + self.seq = seq
|
| + self.pos = pos
|
| +
|
| + def __repr__(self):
|
| + return '<loop pos=%r at %r>' % (
|
| + self.seq[self.pos], self.pos)
|
| +
|
| + def index(self):
|
| + return self.pos
|
| + index = property(index)
|
| +
|
| + def number(self):
|
| + return self.pos + 1
|
| + number = property(number)
|
| +
|
| + def item(self):
|
| + return self.seq[self.pos]
|
| + item = property(item)
|
| +
|
| + def __next__(self):
|
| + try:
|
| + return self.seq[self.pos + 1]
|
| + except IndexError:
|
| + return None
|
| + __next__ = property(__next__)
|
| +
|
| + if sys.version < "3":
|
| + next = __next__
|
| +
|
| + def previous(self):
|
| + if self.pos == 0:
|
| + return None
|
| + return self.seq[self.pos - 1]
|
| + previous = property(previous)
|
| +
|
| + def odd(self):
|
| + return not self.pos % 2
|
| + odd = property(odd)
|
| +
|
| + def even(self):
|
| + return self.pos % 2
|
| + even = property(even)
|
| +
|
| + def first(self):
|
| + return self.pos == 0
|
| + first = property(first)
|
| +
|
| + def last(self):
|
| + return self.pos == len(self.seq) - 1
|
| + last = property(last)
|
| +
|
| + def length(self):
|
| + return len(self.seq)
|
| + length = property(length)
|
| +
|
| + def first_group(self, getter=None):
|
| + """
|
| + Returns true if this item is the start of a new group,
|
| + where groups mean that some attribute has changed. The getter
|
| + can be None (the item itself changes), an attribute name like
|
| + ``'.attr'``, a function, or a dict key or list index.
|
| + """
|
| + if self.first:
|
| + return True
|
| + return self._compare_group(self.item, self.previous, getter)
|
| +
|
| + def last_group(self, getter=None):
|
| + """
|
| + Returns true if this item is the end of a new group,
|
| + where groups mean that some attribute has changed. The getter
|
| + can be None (the item itself changes), an attribute name like
|
| + ``'.attr'``, a function, or a dict key or list index.
|
| + """
|
| + if self.last:
|
| + return True
|
| + return self._compare_group(self.item, self.__next__, getter)
|
| +
|
| + def _compare_group(self, item, other, getter):
|
| + if getter is None:
|
| + return item != other
|
| + elif (isinstance(getter, basestring_)
|
| + and getter.startswith('.')):
|
| + getter = getter[1:]
|
| + if getter.endswith('()'):
|
| + getter = getter[:-2]
|
| + return getattr(item, getter)() != getattr(other, getter)()
|
| + else:
|
| + return getattr(item, getter) != getattr(other, getter)
|
| + elif hasattr(getter, '__call__'):
|
| + return getter(item) != getter(other)
|
| + else:
|
| + return item[getter] != other[getter]
|
|
|