[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