[Checkins] SVN: Sandbox/malthe/chameleon.core/ Reworked repeat-variable logic. An iterator would be realized at any
Malthe Borch
mborch at gmail.com
Tue Nov 25 17:18:20 EST 2008
Log message for revision 93353:
Reworked repeat-variable logic. An iterator would be realized at any
rate, so let's not try to be clever.
Changed:
U Sandbox/malthe/chameleon.core/CHANGES.txt
U Sandbox/malthe/chameleon.core/src/chameleon/core/clauses.py
U Sandbox/malthe/chameleon.core/src/chameleon/core/utils.py
-=-
Modified: Sandbox/malthe/chameleon.core/CHANGES.txt
===================================================================
--- Sandbox/malthe/chameleon.core/CHANGES.txt 2008-11-25 21:38:56 UTC (rev 93352)
+++ Sandbox/malthe/chameleon.core/CHANGES.txt 2008-11-25 22:18:20 UTC (rev 93353)
@@ -4,6 +4,9 @@
HEAD
~~~~
+- Reworked repeat-variable logic. An iterator would be realized at any
+ rate, so let's not try to be clever. [malthe]
+
- Made repeat-variable work with iterables which do not announce their
length before execution. [malthe]
Modified: Sandbox/malthe/chameleon.core/src/chameleon/core/clauses.py
===================================================================
--- Sandbox/malthe/chameleon.core/src/chameleon/core/clauses.py 2008-11-25 21:38:56 UTC (rev 93352)
+++ Sandbox/malthe/chameleon.core/src/chameleon/core/clauses.py 2008-11-25 22:18:20 UTC (rev 93353)
@@ -749,7 +749,7 @@
>>> exec stream.getvalue()
Traceback (most recent call last):
...
- TypeError: Can only repeat over an iterable object (None).
+ TypeError: 'NoneType' object is not iterable
Simple for loop:
Modified: Sandbox/malthe/chameleon.core/src/chameleon/core/utils.py
===================================================================
--- Sandbox/malthe/chameleon.core/src/chameleon/core/utils.py 2008-11-25 21:38:56 UTC (rev 93352)
+++ Sandbox/malthe/chameleon.core/src/chameleon/core/utils.py 2008-11-25 22:18:20 UTC (rev 93353)
@@ -186,53 +186,17 @@
class repeatdict(dict):
def insert(self, key, iterable):
- try:
- # this may seem convoluted, but in some cases, looking up
- # the ``__len__`` attribute may raise an exception, in
- # which case we'll pretend it isn't there; in this case, a
- # safe way to get the length is to coerce the iterable
- # into a tuple from which we can always get the length
- __len__ = getattr(iterable, '__len__')
- except AttributeError:
- # some objects may provide a length but not possess a
- # ``__len__`` in which case we'll try using the builtin
- # method to obtain the length
- try:
- __len__ = length = len(iterable)
- except TypeError:
- # only if this results in a type-error, do we let is
- # pass through; we do not want to mask any errors
- # caused by actual code
- __len__ = None
- except (KeyboardInterrupt, SystemExit):
- # these should never be caught; re-raise exception
- raise
- except:
- __len__ = None
- else:
- # it should be safe to obtain the length from the
- # ``__len__`` method; remove safety gloves.
- length = __len__()
+ """We realize the iterable and extract a new iterable from it;
+ this allows us to keep track of the iteration and make
+ available the repeat dictionary."""
- try:
- # We used to do iterable.__iter__() but, e.g. BTreeItems
- # objects are iterable (via __getitem__) but don't possess
- # an __iter__. call iter(iterable) instead to determine
- # iterability.
- iterator = iter(iterable)
- except TypeError:
- raise TypeError(
- "Can only repeat over an iterable object (%s)." % iterable)
-
- # if no length was obtained, coerce iterable to a tuple first
- if __len__ is None:
- generated = tuple(iterator)
- iterator = iter(generated)
- length = len(generated)
-
- # insert iterable into repeat structure
- self[key] = (iterator, length)
+ if not isinstance(iterable, (tuple, list)):
+ iterable = tuple(iterable)
+ iterator = iter(iterable)
+ length = len(iterable)
+ self[key] = (iterator, length)
+
return iterator
def __getitem__(self, key):
More information about the Checkins
mailing list