diff genshi/template/eval.py @ 703:af57b12e3dd2 experimental-match-fastpaths

merge in trunk up through r818 - fundamentally changed the way MatchSet works, but actually is more consistent now
author aflett
date Mon, 31 Mar 2008 22:47:50 +0000
parents 17f9061d0f74
children d143dd73789b
line wrap: on
line diff
--- a/genshi/template/eval.py
+++ b/genshi/template/eval.py
@@ -139,8 +139,7 @@
         :return: the result of the evaluation
         """
         __traceback_hide__ = 'before_and_this'
-        _globals = self._globals()
-        _globals['__data__'] = data
+        _globals = self._globals(data)
         return eval(self.code, _globals, {'__data__': data})
 
 
@@ -161,8 +160,7 @@
         :param data: a mapping containing the data to execute in
         """
         __traceback_hide__ = 'before_and_this'
-        _globals = self._globals()
-        _globals['__data__'] = data
+        _globals = self._globals(data)
         exec self.code in _globals, data
 
 
@@ -248,15 +246,16 @@
 class LookupBase(object):
     """Abstract base class for variable lookup implementations."""
 
-    def globals(cls):
+    def globals(cls, data):
         """Construct the globals dictionary to use as the execution context for
         the expression or suite.
         """
         return {
+            '__data__': data,
             '_lookup_name': cls.lookup_name,
             '_lookup_attr': cls.lookup_attr,
             '_lookup_item': cls.lookup_item,
-            'UndefinedError': UndefinedError
+            'UndefinedError': UndefinedError,
         }
     globals = classmethod(globals)
 
@@ -270,18 +269,22 @@
         return val
     lookup_name = classmethod(lookup_name)
 
-    def lookup_attr(cls, data, obj, key):
+    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):
-                val = cls.undefined(key, owner=obj)
+        try:
+            val = getattr(obj, key)
+        except AttributeError:
+            if hasattr(obj.__class__, key):
+                raise
+            else:
+                try:
+                    val = obj[key]
+                except (KeyError, TypeError):
+                    val = cls.undefined(key, owner=obj)
         return val
     lookup_attr = classmethod(lookup_attr)
 
-    def lookup_item(cls, data, obj, key):
+    def lookup_item(cls, obj, key):
         __traceback_hide__ = True
         if len(key) == 1:
             key = key[0]
@@ -754,12 +757,12 @@
 
     def visitGetattr(self, node):
         return ast.CallFunc(ast.Name('_lookup_attr'), [
-            ast.Name('__data__'), self.visit(node.expr),
+            self.visit(node.expr),
             ast.Const(node.attrname)
         ])
 
     def visitSubscript(self, node):
         return ast.CallFunc(ast.Name('_lookup_item'), [
-            ast.Name('__data__'), self.visit(node.expr),
+            self.visit(node.expr),
             ast.Tuple([self.visit(sub) for sub in node.subs])
         ])
Copyright (C) 2012-2017 Edgewall Software