[Checkins] SVN: z3c.pt/trunk/ Fixed bug where a getattr-expression
(the dot operator) would result in two or three accesses.
Malthe Borch
mborch at gmail.com
Fri Feb 22 18:46:15 EST 2008
Log message for revision 84151:
Fixed bug where a getattr-expression (the dot operator) would result in two or three accesses.
Changed:
U z3c.pt/trunk/setup.py
U z3c.pt/trunk/z3c/pt/BENCHMARKS.txt
U z3c.pt/trunk/z3c/pt/codegen.py
U z3c.pt/trunk/z3c/pt/codegen.txt
U z3c.pt/trunk/z3c/pt/pagetemplate.py
-=-
Modified: z3c.pt/trunk/setup.py
===================================================================
--- z3c.pt/trunk/setup.py 2008-02-22 22:48:17 UTC (rev 84150)
+++ z3c.pt/trunk/setup.py 2008-02-22 23:46:13 UTC (rev 84151)
@@ -1,6 +1,6 @@
from setuptools import setup, find_packages
-version = '0.4'
+version = '0.4.1'
setup(name='z3c.pt',
version=version,
Modified: z3c.pt/trunk/z3c/pt/BENCHMARKS.txt
===================================================================
--- z3c.pt/trunk/z3c/pt/BENCHMARKS.txt 2008-02-22 22:48:17 UTC (rev 84150)
+++ z3c.pt/trunk/z3c/pt/BENCHMARKS.txt 2008-02-22 23:46:13 UTC (rev 84151)
@@ -16,8 +16,7 @@
50x factor in the 'Hello World' benchmark versus a pure python
implementation.
-Certainly a specialized implementation will always be faster. But
-there's still some room for improvement.
+Certainly a specialized implementation will always be faster.
Benchmark source code
---------------------
@@ -67,7 +66,7 @@
... </tr>
... </table>""")
- >>> for i in range(40): a = template(table=table)
+ >>> # for i in range(40): a = template(table=table)
>>> template = z3PageTemplate()
>>> template.pt_edit("""\
Modified: z3c.pt/trunk/z3c/pt/codegen.py
===================================================================
--- z3c.pt/trunk/z3c/pt/codegen.py 2008-02-22 22:48:17 UTC (rev 84150)
+++ z3c.pt/trunk/z3c/pt/codegen.py 2008-02-22 23:46:13 UTC (rev 84151)
@@ -7,6 +7,33 @@
CONSTANTS = frozenset(['False', 'True', 'None', 'NotImplemented', 'Ellipsis'])
+UNDEFINED = object()
+
+class Lookup(object):
+ """Abstract base class for variable lookup implementations."""
+
+ def globals(cls):
+ """Construct the globals dictionary to use as the execution context for
+ the expression or suite.
+ """
+ return {
+ '_lookup_attr': cls.lookup_attr,
+ }
+
+ globals = classmethod(globals)
+
+ @classmethod
+ def lookup_attr(cls, obj, key):
+ __traceback_hide__ = True
+ val = getattr(obj, key, UNDEFINED)
+ if val is UNDEFINED:
+ try:
+ val = obj[key]
+ except (KeyError, TypeError):
+ raise AttributeError(key)
+
+ return val
+
class TemplateASTTransformer(ASTTransformer):
def __init__(self):
self.locals = [CONSTANTS]
@@ -22,20 +49,12 @@
if hasattr(node.expr, 'name') and node.expr.name.startswith('_'):
return ast.Getattr(node.expr, node.attrname)
- expr = self.visit(node.expr)
- name = ast.Const(node.attrname)
-
- # hasattr(obj, key) and getattr(obj, key) or not
- # hasattr(obj, key) and obj[key]
- return ast.Or([ast.And(
- [ast.CallFunc(ast.Name('hasattr'), [expr, name], None, None),
- ast.CallFunc(ast.Name('getattr'), [expr, name], None, None)]),
- ast.And([
- ast.Not(ast.CallFunc(ast.Name('hasattr'), [expr, name], None, None)),
- ast.Subscript(expr, 'OP_APPLY', [name])])])
+ return ast.CallFunc(ast.Name('_lookup_attr'), [
+ self.visit(node.expr), ast.Const(node.attrname)
+ ])
class Suite(object):
- __slots__ = ['code']
+ __slots__ = ['code', '_globals']
xform = TemplateASTTransformer
mode = 'exec'
@@ -54,6 +73,7 @@
gen = ModuleCodeGenerator(tree)
gen.optimized = True
+ self._globals = Lookup.globals()
self.code = gen.getCode()
def __hash__(self):
Modified: z3c.pt/trunk/z3c/pt/codegen.txt
===================================================================
--- z3c.pt/trunk/z3c/pt/codegen.txt 2008-02-22 22:48:17 UTC (rev 84150)
+++ z3c.pt/trunk/z3c/pt/codegen.txt 2008-02-22 23:46:13 UTC (rev 84151)
@@ -14,7 +14,7 @@
>>> suite = Suite("""\
... print 'Hello World!'
... """)
- >>> exec suite.code
+ >>> exec suite.code in suite._globals
Hello World!
AST transformations
@@ -28,4 +28,4 @@
... a = {'b': 1}
... assert a['b'] == a.b
... """)
- >>> exec suite.code
+ >>> exec suite.code in suite._globals
Modified: z3c.pt/trunk/z3c/pt/pagetemplate.py
===================================================================
--- z3c.pt/trunk/z3c/pt/pagetemplate.py 2008-02-22 22:48:17 UTC (rev 84150)
+++ z3c.pt/trunk/z3c/pt/pagetemplate.py 2008-02-22 23:46:13 UTC (rev 84151)
@@ -14,8 +14,7 @@
source, _globals = translation.translate(self.body, params)
suite = codegen.Suite(source)
- self.source = source
-
+ _globals.update(suite._globals)
_locals = {}
exec suite.code in _globals, _locals
More information about the Checkins
mailing list