[Checkins] SVN: Sandbox/malthe/chameleon.zpt/ Fixed semi-colon escape incompatibility; removed -method.
Malthe Borch
mborch at gmail.com
Sat Nov 15 21:05:43 EST 2008
Log message for revision 93000:
Fixed semi-colon escape incompatibility; removed -method.
Changed:
U Sandbox/malthe/chameleon.zpt/CHANGES.txt
U Sandbox/malthe/chameleon.zpt/src/chameleon/zpt/expressions.py
-=-
Modified: Sandbox/malthe/chameleon.zpt/CHANGES.txt
===================================================================
--- Sandbox/malthe/chameleon.zpt/CHANGES.txt 2008-11-16 01:22:15 UTC (rev 92999)
+++ Sandbox/malthe/chameleon.zpt/CHANGES.txt 2008-11-16 02:05:43 UTC (rev 93000)
@@ -4,6 +4,13 @@
Head
~~~~
+- `validate`-method is no longer formally required; errors are
+ expected to be raised by the `translate`-method. [malthe]
+
+- Formalized character escape requirement; this allows compatibility
+ with ZPT with regards to semi-colon escapes in attribute
+ declarations. [malthe]
+
- Allow chained pragmas. [malthe]
1.0b3 (released 11/12/2008)
Modified: Sandbox/malthe/chameleon.zpt/src/chameleon/zpt/expressions.py
===================================================================
--- Sandbox/malthe/chameleon.zpt/src/chameleon/zpt/expressions.py 2008-11-16 01:22:15 UTC (rev 92999)
+++ Sandbox/malthe/chameleon.zpt/src/chameleon/zpt/expressions.py 2008-11-16 02:05:43 UTC (rev 93000)
@@ -115,12 +115,9 @@
"""Semi-colon separated variable definitions.
>>> class MockExpressionTranslator(ExpressionTranslator):
- ... def validate(self, string):
- ... if string == '' or ';' in string:
+ ... def tales(self, string, escape=None):
+ ... if string == '' or ';' in string.replace("';'", "''"):
... raise SyntaxError()
- ...
- ... def tales(self, string):
- ... self.validate(string)
... return types.value(string.strip())
>>> definitions = MockExpressionTranslator().definitions
@@ -135,7 +132,14 @@
>>> definitions("variable1 expression1; variable2 expression2")
definitions((declaration('variable1'), value('expression1')),
(declaration('variable2'), value('expression2')))
+
+ Defines are only split on semi-colon if a valid declaration is
+ available.
+ >>> definitions("variable1 ';'+expression1; variable2 expression2")
+ definitions((declaration('variable1'), value("';'+expression1")),
+ (declaration('variable2'), value('expression2')))
+
Tuple define:
>>> definitions("(variable1, variable2) (expression1, expression2)")
@@ -224,7 +228,7 @@
i += 3
try:
- expr = self.tales(string[i:])
+ expr = self.tales(string[i:], ';')
j = -1
except SyntaxError, e:
expr = None
@@ -236,7 +240,7 @@
raise e
try:
- expr = self.tales(string[i:j])
+ expr = self.tales(string[i:j], ';')
except SyntaxError, e:
if string.rfind(';', i, j) > 0:
continue
@@ -264,10 +268,7 @@
"""String output; supports 'structure' keyword.
>>> class MockExpressionTranslator(ExpressionTranslator):
- ... def validate(self, string):
- ... return True
- ...
- ... def translate(self, string):
+ ... def translate(self, string, escape=None):
... return types.value(string)
>>> output = MockExpressionTranslator().output
@@ -292,16 +293,13 @@
return types.escape((expression,))
- def tales(self, string):
+ def tales(self, string, escape=None):
"""We need to implement the ``validate`` and
``translate``-methods. Let's define that an expression is
valid if it contains an odd number of characters.
>>> class MockExpressionTranslator(ExpressionTranslator):
- ... def validate(self, string):
- ... return True
- ...
- ... def translate(self, string):
+ ... def translate(self, string, escape=None):
... return types.value(string)
>>> tales = MockExpressionTranslator().tales
@@ -311,7 +309,6 @@
>>> tales('a|b')
parts(value('a'), value('b'))
-
"""
string = string.replace('\n', '').strip()
@@ -343,15 +340,14 @@
expr = string[i:j]
try:
- translator.validate(expr)
+ value = translator.translate(expr, escape)
except Exception, e:
if j < len(string):
continue
# re-raise with traceback
- translator.validate(expr)
+ value = translator.translate(expr, escape)
- value = translator.translate(expr)
parts.append(value)
translator = self
@@ -368,7 +364,7 @@
class PythonTranslator(ExpressionTranslator):
"""Implements Python expression translation."""
- def validate(self, string):
+ def translate(self, string, escape=None):
"""We use the ``parser`` module to determine if
an expression is a valid python expression."""
@@ -376,8 +372,7 @@
string = string.encode('utf-8')
parser.expr(string.strip())
-
- def translate(self, string):
+
if isinstance(string, str):
string = string.decode('utf-8')
@@ -396,47 +391,43 @@
def __init__(self, translator):
self.translator = translator
- def validate(self, string):
- self.split(string)
-
- def translate(self, string):
- return types.join(self.split(string))
-
- def split(self, string):
- parts = super(StringTranslator, self).split(string)
- if parts is not None:
- return map(
+ def translate(self, string, escape=None):
+ parts = self.split(string)
+
+ if escape is not None:
+ parts = map(
lambda part: isinstance(part, types.expression) and \
- part or self._unescape(part), parts)
+ part or self._unescape(part, escape), parts)
- def _unescape(self, string):
+ return types.join(parts)
+
+ def _unescape(self, string, symbol):
"""
>>> unescape = StringTranslator(None)._unescape
- >>> unescape('string:Hello World')
+ >>> unescape('string:Hello World', ';')
'string:Hello World'
- >>> unescape('; string:Hello World')
+ >>> unescape('; string:Hello World', ';')
Traceback (most recent call last):
...
- SyntaxError: Semi-colons in string-expressions must be escaped.
+ SyntaxError: Must escape symbol ';'.
- >>> unescape(';; string:Hello World')
+ >>> unescape(';; string:Hello World', ';')
'; string:Hello World'
- >>> unescape('string:Hello World;')
+ >>> unescape('string:Hello World;', ';')
'string:Hello World;'
-
"""
-
- i = string.rfind(';')
+
+ i = string.rfind(symbol)
if i < 0 or i == len(string) - 1:
return string
- j = string.rfind(';'+';')
+ j = string.rfind(symbol+symbol)
if j < 0 or i != j + 1:
raise SyntaxError(
- "Semi-colons in string-expressions must be escaped.")
+ "Must escape symbol %s." % repr(symbol))
- return string.replace(';;', ';')
+ return string.replace(symbol+symbol, symbol)
More information about the Checkins
mailing list