[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