[Zope3-checkins] CVS: Zope3/src/zope/tales - expressions.py:1.4.2.1 interfaces.py:1.1.2.1 tales.py:1.6.2.1

Grégoire Weber zope@i-con.ch
Sun, 22 Jun 2003 10:27:32 -0400


Update of /cvs-repository/Zope3/src/zope/tales
In directory cvs.zope.org:/tmp/cvs-serv28993/src/zope/tales

Modified Files:
      Tag: cw-mail-branch
	expressions.py interfaces.py tales.py 
Log Message:
Synced up with HEAD

=== Zope3/src/zope/tales/expressions.py 1.4 => 1.4.2.1 ===
--- Zope3/src/zope/tales/expressions.py:1.4	Tue May 20 16:29:21 2003
+++ Zope3/src/zope/tales/expressions.py	Sun Jun 22 10:27:00 2003
@@ -47,7 +47,7 @@
     def __init__(self, path, traverser, engine):
         self._traverser = traverser
         self._engine = engine
-        
+
         # Parse path
         compiledpath = []
         currentpath = []
@@ -85,10 +85,10 @@
 
         if currentpath:
             compiledpath.append(tuple(currentpath))
-            
+
         first = compiledpath[0]
         base = first[0]
-        
+
         if callable(first):
             # check for initial function
             raise CompilerError(
@@ -97,14 +97,13 @@
             # check for initial ?
             raise CompilerError(
                 'Dynamic name specified in first subpath element')
-        
+
         if not _valid_name(base):
             raise CompilerError, 'Invalid variable name "%s"' % element
         self._base = base
         compiledpath[0]=first[1:]
         self._compiled_path = tuple(compiledpath)
 
-        
     def _eval(self, econtext,
               list=list, isinstance=isinstance):
         vars = econtext.vars


=== Zope3/src/zope/tales/interfaces.py 1.1 => 1.1.2.1 ===
--- Zope3/src/zope/tales/interfaces.py:1.1	Tue May 20 16:29:38 2003
+++ Zope3/src/zope/tales/interfaces.py	Sun Jun 22 10:27:00 2003
@@ -32,8 +32,15 @@
         For example, with a TAL statement like: tal:repeat="item items",
         an iterator will be assigned to "repeat/item".  The iterator
         provides a number of handy methods useful in writing TAL loops.
+
+        The results are undefined of calling any of the methods except
+        'length' before the first iteration.
         """
 
+        def index():
+            """Return the position (starting with "0") within the iteration
+            """
+
         def number():
             """Return the position (starting with "1") within the iteration
             """
@@ -46,6 +53,14 @@
             """Return whether the current position is odd
             """
 
+        def start():
+            """Return whether the current position is the first position
+            """
+
+        def end():
+            """Return whether the current position is the last position
+            """
+
         def letter():
             """Return the position (starting with "a") within the iteration
             """
@@ -62,16 +77,8 @@
             """Return the position (starting with "I") within the iteration
             """
 
-        def start():
-            """Return whether the current position is the first position
-            """
-
-        def end():
-            """Return whether the current position is the last position
-            """
-
         def item():
-            """Return whether the item at the current position
+            """Return the item at the current position
             """
 
         def length():
@@ -80,4 +87,3 @@
             Note that this may fail if the TAL iterator was created on a Python
             iterator.
             """
-    


=== Zope3/src/zope/tales/tales.py 1.6 => 1.6.2.1 ===
--- Zope3/src/zope/tales/tales.py:1.6	Tue May 20 16:29:59 2003
+++ Zope3/src/zope/tales/tales.py	Sun Jun 22 10:27:00 2003
@@ -23,7 +23,7 @@
 from types import StringTypes
 
 from zope.proxy import proxy_compatible_isinstance as isinstance_ex
-from zope.proxy.context.wrapper import getbaseobject
+from zope.context.wrapper import getbaseobject
 from zope.tales.interfaces import ITALESIterator
 from zope.interface import implements
 
@@ -33,7 +33,8 @@
     tal = None
 
 if tal:
-    from zope.tal.interfaces import ITALExpressionCompiler, ITALExpressionEngine
+    from zope.tal.interfaces import ITALExpressionEngine
+    from zope.tal.interfaces import ITALExpressionCompiler
     from zope.tal.interfaces import ITALExpressionErrorInfo
     from zope.tales.interfaces import ITALESIterator
 
@@ -69,29 +70,29 @@
 
     def __init__(self, name, seq, context):
         """Construct an iterator
-        
+
         Iterators are defined for a name, a sequence, or an iterator and a
         context, where a context simply has a setLocal method:
-        
+
         >>> context = Context(ExpressionEngine(), {})
         >>> it = Iterator('foo', ("apple", "pear", "orange"), context)
-        
+
         A local variable is not set until the iterator is used:
-        
+
         >>> int("foo" in context.vars)
         0
-        
+
         We can create an iterator on an empty sequence:
-        
+
         >>> it = Iterator('foo', (), context)
-        
+
         An iterator works as well:
-        
+
         >>> it = Iterator('foo', {"apple":1, "pear":1, "orange":1}, context)
         >>> it = Iterator('foo', {}, context)
 
-        """ 
-        
+        """
+
         self._seq = seq
         self._iter = i = iter(seq)
         self._nextIndex = 0
@@ -163,9 +164,32 @@
         self._setLocal(self._name, v)
         return 1
 
+    def index(self):
+        """Get the iterator index
+
+        >>> context = Context(ExpressionEngine(), {})
+        >>> it = Iterator('foo', ("apple", "pear", "orange"), context)
+        >>> int(bool(it.next()))
+        1
+        >>> it.index()
+        0
+        >>> int(bool(it.next()))
+        1
+        >>> it.index()
+        1
+        >>> int(bool(it.next()))
+        1
+        >>> it.index()
+        2
+        """
+        index = self._nextIndex - 1
+        if index < 0:
+            raise TypeError("No iteration position") 
+        return index
+
     def number(self):
         """Get the iterator position
-        
+
         >>> context = Context(ExpressionEngine(), {})
         >>> it = Iterator('foo', ("apple", "pear", "orange"), context)
         >>> int(bool(it.next()))
@@ -185,7 +209,7 @@
 
     def even(self):
         """Test whether the position is even
-        
+
         >>> context = Context(ExpressionEngine(), {})
         >>> it = Iterator('foo', ("apple", "pear", "orange"), context)
         >>> int(bool(it.next()))
@@ -205,7 +229,7 @@
 
     def odd(self):
         """Test whether the position is odd
-        
+
         >>> context = Context(ExpressionEngine(), {})
         >>> it = Iterator('foo', ("apple", "pear", "orange"), context)
         >>> int(bool(it.next()))
@@ -225,7 +249,7 @@
 
     def letter(self, base=ord('a'), radix=26):
         """Get the iterator position as a lower-case letter
-        
+
         >>> context = Context(ExpressionEngine(), {})
         >>> it = Iterator('foo', ("apple", "pear", "orange"), context)
         >>> int(bool(it.next()))
@@ -252,7 +276,7 @@
 
     def Letter(self):
         """Get the iterator position as an upper-case letter
-        
+
         >>> context = Context(ExpressionEngine(), {})
         >>> it = Iterator('foo', ("apple", "pear", "orange"), context)
         >>> int(bool(it.next()))
@@ -275,7 +299,7 @@
                     (100,'C'),(90,'XC'),(50,'L'),(40,'XL'),
                     (10,'X'),(9,'IX'),(5,'V'),(4,'IV'),(1,'I')) ):
         """Get the iterator position as an upper-case roman numeral
-        
+
         >>> context = Context(ExpressionEngine(), {})
         >>> it = Iterator('foo', ("apple", "pear", "orange"), context)
         >>> int(bool(it.next()))
@@ -300,7 +324,7 @@
 
     def roman(self):
         """Get the iterator position as a lower-case roman numeral
-        
+
         >>> context = Context(ExpressionEngine(), {})
         >>> it = Iterator('foo', ("apple", "pear", "orange"), context)
         >>> int(bool(it.next()))
@@ -320,7 +344,7 @@
 
     def start(self):
         """Test whether the position is the first position
-        
+
         >>> context = Context(ExpressionEngine(), {})
         >>> it = Iterator('foo', ("apple", "pear", "orange"), context)
         >>> int(bool(it.next()))
@@ -349,7 +373,7 @@
 
     def end(self):
         """Test whether the position is the last position
-        
+
         >>> context = Context(ExpressionEngine(), {})
         >>> it = Iterator('foo', ("apple", "pear", "orange"), context)
         >>> int(bool(it.next()))
@@ -377,7 +401,7 @@
 
     def item(self):
         """Get the iterator value
-        
+
         >>> context = Context(ExpressionEngine(), {})
         >>> it = Iterator('foo', ("apple", "pear", "orange"), context)
         >>> int(bool(it.next()))
@@ -400,25 +424,27 @@
         1
 
         """
+        if self._nextIndex == 0:
+            raise TypeError("No iteration position") 
         return self._item
 
     def length(self):
         """Get the length of the iterator sequence
-        
+
         >>> context = Context(ExpressionEngine(), {})
         >>> it = Iterator('foo', ("apple", "pear", "orange"), context)
         >>> it.length()
         3
 
         You can even get the length of a mapping:
-        
+
         >>> it = Iterator('foo', {"apple":1, "pear":2, "orange":3}, context)
         >>> it.length()
         3
 
         But you can't get the length if an iterable without a length
         was provided:
-        
+
         >>> it = Iterator('foo', iter({"apple":1, "pear":2}), context)
         >>> it.length()
         Traceback (most recent call last):
@@ -426,17 +452,13 @@
         TypeError: len() of unsized object
 
         """
-        
         return len(self._seq)
 
 
-
 class ErrorInfo:
     """Information about an exception passed to an on-error handler."""
-
-
     if tal:
-        __implements__ = ITALExpressionErrorInfo
+        implements(ITALExpressionErrorInfo)
 
     def __init__(self, err, position=(None, None)):
         if isinstance(err, Exception):
@@ -449,7 +471,6 @@
         self.offset = position[1]
 
 
-
 class ExpressionEngine:
     '''Expression Engine
 
@@ -458,9 +479,8 @@
     these handlers.  It can provide an expression Context, which is
     capable of holding state and evaluating compiled expressions.
     '''
-
     if tal:
-        __implements__ = ITALExpressionCompiler
+        implements(ITALExpressionCompiler)
 
     def __init__(self):
         self.types = {}
@@ -497,11 +517,10 @@
 
               def lower(self):
                  return self.context.lower()
-            
+
             engine.registerFunctionNamespace('string',stringFuncs)
-	"""
-	
-	self.namespaces[namespacename] = namespacecallable
+        """
+        self.namespaces[namespacename] = namespacecallable
 
 
     def getFunctionNamespace(self, namespacename):
@@ -569,7 +588,7 @@
     '''
 
     if tal:
-        __implements__ = ITALExpressionEngine
+        implements(ITALExpressionEngine)
 
     position = (None, None)
     source_file = None
@@ -590,7 +609,7 @@
 
         # Keep track of what needs to be popped as each scope ends.
         self._scope_stack = []
-        
+
     def setContext(self, name, value):
         # Hook to allow subclasses to do things like adding security proxies
         self.contexts[name] = value
@@ -604,7 +623,6 @@
         self._vars_stack.pop()
         self.vars = self._vars_stack[-1]
 
-        
         scope = self._scope_stack.pop()
         # Pop repeat variables, if any
         i = len(scope) 
@@ -678,6 +696,7 @@
 
 class TALESTracebackSupplement:
     """Implementation of zope.exceptions.ITracebackSupplement"""
+
     def __init__(self, context, expression):
         self.context = context
         self.source_url = context.source_file