[Checkins] SVN: z3c.pt/trunk/z3c/pt/ Refactor scoping
Daniel Nouri
daniel.nouri at gmail.com
Sat Dec 22 19:06:02 EST 2007
Log message for revision 82404:
Refactor scoping
Changed:
U z3c.pt/trunk/z3c/pt/clauses.py
U z3c.pt/trunk/z3c/pt/io.py
U z3c.pt/trunk/z3c/pt/translation.py
-=-
Modified: z3c.pt/trunk/z3c/pt/clauses.py
===================================================================
--- z3c.pt/trunk/z3c/pt/clauses.py 2007-12-22 21:28:32 UTC (rev 82403)
+++ z3c.pt/trunk/z3c/pt/clauses.py 2007-12-23 00:06:01 UTC (rev 82404)
@@ -1,10 +1,11 @@
from attributes import expression
+from attributes import definition
+
import utils
class Assign(object):
"""
>>> from z3c.pt.io import CodeIO; stream = CodeIO()
- >>> _scope = []
Simple assignment:
@@ -23,7 +24,15 @@
>>> b == 1
True
>>> assign.end(stream)
-
+
+ Try-except chain part 2:
+
+ >>> assign = Assign(expression("'abc' | 1"))
+ >>> assign.begin(stream, 'b')
+ >>> exec stream.getvalue()
+ >>> b == 'abc'
+ True
+ >>> assign.end(stream)
"""
def __init__(self, expressions, variable=None):
@@ -54,7 +63,6 @@
class Define(object):
"""
>>> from z3c.pt.io import CodeIO; stream = CodeIO()
- >>> _scope = []
Variable scope:
@@ -65,7 +73,6 @@
>>> a is b
True
>>> del a
- >>> _scope.remove('a')
>>> define.end(stream)
>>> exec stream.getvalue()
>>> a
@@ -89,7 +96,7 @@
>>> define2.end(stream)
>>> define1.end(stream)
>>> del a; del c
- >>> _scope.remove('a'); _scope.remove('c')
+ >>> stream.scope[-1].remove('a'); stream.scope[-1].remove('c')
>>> exec stream.getvalue()
>>> a
Traceback (most recent call last):
@@ -105,7 +112,7 @@
Tuple assignments:
>>> stream = CodeIO()
- >>> define = Define("(e, f)", expression("[1, 2]"))
+ >>> define = Define(['e', 'f'], expression("[1, 2]"))
>>> define.begin(stream)
>>> exec stream.getvalue()
>>> e == 1 and f == 2
@@ -114,8 +121,12 @@
Verify scope is preserved on tuple assignment:
+ >>> stream = CodeIO()
>>> e = None; f = None
- >>> _scope.append('e'); _scope.append('f')
+ >>> stream.scope[-1].add('e'); stream.scope[-1].add('f')
+ >>> stream.scope.append(set())
+ >>> define.begin(stream)
+ >>> define.end(stream)
>>> exec stream.getvalue()
>>> e is None and f is None
True
@@ -134,7 +145,8 @@
>>> stream = CodeIO()
>>> a = 1
- >>> _scope.append('a')
+ >>> stream.scope[-1].add('a')
+ >>> stream.scope.append(set())
>>> define = Define("a", expression("2"))
>>> define.begin(stream)
>>> define.end(stream)
@@ -143,7 +155,7 @@
1
"""
- def __init__(self, definition, expression, scope=()):
+ def __init__(self, definition, expression):
if not isinstance(definition, (list, tuple)):
definition = (definition,)
@@ -152,45 +164,48 @@
else:
variable = u"(%s,)" % ", ".join(definition)
- self.assign = Assign(expression, variable)
-
- # only register definitions for variables that have not
- # been defined in this scope
- self.definitions = [var for var in definition if var not in scope]
-
- if scope:
- scope.extend(self.definitions)
- if not scope:
- scope = utils.scope()
-
- self.scope = scope
+ self.assign = Assign(expression, variable)
+ self.definitions = definition
def begin(self, stream):
- temp = stream.savevariable(self.scope, '{}')
-
# save local variables already in in scope
for var in self.definitions:
- stream.write("if '%s' in _scope: %s['%s'] = %s" % (var, temp, var, var))
- stream.write("else: _scope.append('%s')" % var)
-
+ temp = stream.save()
+
+ # If we didn't set the variable in this scope already
+ if var not in stream.scope[-1]:
+
+ # we'll check if it's set in one of the older scopes
+ for scope in stream.scope[:-1]:
+ if var in scope:
+ # in which case we back it up
+ stream.write('%s = %s' % (temp, var))
+
+ stream.scope[-1].add(var)
+
self.assign.begin(stream)
def end(self, stream):
- temp = stream.restorevariable(self.scope)
+ self.assign.end(stream)
- self.assign.end(stream)
-
+ # back come the variables that were already in scope in the
+ # first place
for var in reversed(self.definitions):
- stream.write("if '%s' in %s:" % (var, temp))
- stream.indent()
- stream.write("%s = %s['%s']" % (var, temp, var))
- stream.outdent()
- stream.write("else:")
- stream.indent()
- stream.write("del %s" % var)
- stream.write("_scope.remove('%s')" % var)
- stream.outdent()
-
+ temp = stream.restore()
+
+ # If we set the variable in this scope already
+ if var in stream.scope[-1]:
+
+ # we'll check if it's set in one of the older scopes
+ for scope in stream.scope[:-1]:
+ if var in scope:
+ # in which case we restore it
+ stream.write('%s = %s' % (var, temp))
+ stream.scope[-1].remove(var)
+ break
+ else:
+ stream.write("del %s" % var)
+
class Condition(object):
"""
>>> from z3c.pt.io import CodeIO
@@ -284,7 +299,6 @@
"""
>>> from z3c.pt.io import CodeIO
>>> from StringIO import StringIO
- >>> _scope = []
>>> _out = StringIO(); stream = CodeIO()
>>> tag = Tag('div', dict(alt=expression(repr('Hello World!'))))
@@ -338,7 +352,6 @@
class Repeat(object):
"""
>>> from z3c.pt.io import CodeIO; stream = CodeIO()
- >>> _scope = []
We need to set up the repeat object.
@@ -363,7 +376,7 @@
def __init__(self, v, e, scope=()):
self.variable = v
- self.define = Define(v, expression("None"), scope)
+ self.define = Define(v, expression("None"))
self.assign = Assign(e)
def begin(self, stream):
Modified: z3c.pt/trunk/z3c/pt/io.py
===================================================================
--- z3c.pt/trunk/z3c/pt/io.py 2007-12-22 21:28:32 UTC (rev 82403)
+++ z3c.pt/trunk/z3c/pt/io.py 2007-12-23 00:06:01 UTC (rev 82404)
@@ -22,48 +22,21 @@
self.indentation = indentation
self.indentation_string = indentation_string
self.queue = u''
- self.scope = {}
+ self.scope = [set()]
+
+ self._variables = {}
self.t_counter = 0
- self.v_counter = 0
- def save(self, variable=None):
+ def save(self):
self.t_counter += 1
- if variable:
- self.write("%s%d = %s" % (self.t_prefix, self.t_counter, variable))
- else:
- return "%s%d" % (self.t_prefix, self.t_counter)
+ return "%s%d" % (self.t_prefix, self.t_counter)
- def restore(self, variable=None):
- if variable:
- self.write("%s = %s%d" % (variable, self.t_prefix, self.t_counter))
- else:
- return "%s%d" % (self.t_prefix, self.t_counter)
-
+ def restore(self):
+ var = "%s%d" % (self.t_prefix, self.t_counter)
self.t_counter -= 1
-
- def savevariable(self, obj, expression="None"):
- if obj in self.scope:
- return self.scope[obj]
-
- self.v_counter += 1
- variable = "%s%d" % (self.v_prefix, self.v_counter)
-
- self.write("%s = %s" % (variable, expression))
-
- self.scope[obj] = variable
- return variable
-
- def restorevariable(self, obj, expression="None"):
- if obj in self.scope:
- return self.scope[obj]
-
- variable = "%s%d" % (self.v_prefix, self.v_counter)
- self.v_counter -= 1
-
- self.scope[obj] = variable
- return variable
-
+ return var
+
def indent(self, amount=1):
self.cook()
self.indentation += amount
Modified: z3c.pt/trunk/z3c/pt/translation.py
===================================================================
--- z3c.pt/trunk/z3c/pt/translation.py 2007-12-22 21:28:32 UTC (rev 82403)
+++ z3c.pt/trunk/z3c/pt/translation.py 2007-12-23 00:06:01 UTC (rev 82404)
@@ -11,7 +11,6 @@
\tglobal utils
\t_out = utils.initialize_stream()
-\t_scope = locals().keys()
\t(_attributes, repeat) = utils.initialize_tal()
\t(_domain, _translate) = utils.initialize_i18n()
@@ -32,10 +31,12 @@
class Element(lxml.etree.ElementBase):
def begin(self, stream):
+ stream.scope.append(set())
stream.begin(self.clauses())
def end(self, stream):
stream.end(self.clauses())
+ stream.scope.pop()
def body(self, stream):
skip = self.replace or self.content or self.i18n_translate is not None
@@ -51,16 +52,14 @@
def clauses(self):
_ = []
- scope = utils.scope()
-
# i18n domain
if self.i18n_domain is not None:
- _.append(clauses.Define("_domain", [repr(self.i18n_domain)], scope))
+ _.append(clauses.Define("_domain", [repr(self.i18n_domain)]))
# defines
if self.define is not None:
for variables, expression in self.define:
- _.append(clauses.Define(variables, expression, scope))
+ _.append(clauses.Define(variables, expression))
# condition
if self.condition is not None:
@@ -71,7 +70,7 @@
variables, expression = self.repeat
if len(variables) != 1:
raise ValueError, "Cannot unpack more than one variable in a repeat statement."
- _.append(clauses.Repeat(variables[0], expression, scope))
+ _.append(clauses.Repeat(variables[0], expression))
# tag tail (deferred)
if self.tail:
@@ -131,7 +130,7 @@
name = element.i18n_name
subclauses = []
- subclauses.append(clauses.Define('_out', ['utils.initialize_stream()'], scope))
+ subclauses.append(clauses.Define('_out', ['utils.initialize_stream()']))
subclauses.append(clauses.Group(element.clauses()))
subclauses.append(clauses.Assign(['_out.getvalue()'],
"%s['%s']" % (mapping, name)))
@@ -275,6 +274,8 @@
stream = io.CodeIO(indentation=1, indentation_string="\t")
+ stream.scope.append(set(params + ['_out']))
+
root.visit(stream)
code = stream.getvalue()
More information about the Checkins
mailing list