changeset 731:01bdf155db95 trunk

Workaround for a Python 2.4 bug that broke star imports in template code blocks. Closes #221. Many thanks to Armin Ronacher for the patch.
author cmlenz
date Sun, 01 Jun 2008 20:09:28 +0000
parents 5e9d250ad3ad
children 8825ac5014b1
files genshi/template/base.py genshi/template/eval.py genshi/template/tests/eval.py
diffstat 3 files changed, 43 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/genshi/template/base.py
+++ b/genshi/template/base.py
@@ -244,6 +244,10 @@
         """
         return [(key, self.get(key)) for key in self.keys()]
 
+    def update(self, mapping):
+        """Update the context from the mapping provided."""
+        self.frames[0].update(mapping)
+
     def push(self, data):
         """Push a new scope on the stack.
         
--- a/genshi/template/eval.py
+++ b/genshi/template/eval.py
@@ -33,6 +33,28 @@
            'Undefined', 'UndefinedError']
 __docformat__ = 'restructuredtext en'
 
+# Check for a Python 2.4 bug in the eval loop
+try:
+    class _FakeMapping(object):
+        __getitem__ = __setitem__ = lambda *a: None
+    exec 'from sys import *' in {}, _FakeMapping()
+except SystemError:
+    has_star_import_bug = True
+else:
+    has_star_import_bug = False
+del _FakeMapping
+
+def _star_import_patch(mapping, modname):
+    """This function is used as helper if a Python version with a broken
+    star-import opcode is in use.
+    """
+    module = __import__(modname, None, None, ['__all__'])
+    if hasattr(module, '__all__'):
+        members = module.__all__
+    else:
+        members = [x for x in module.__dict__ if not x.startswith('_')]
+    mapping.update((name, getattr(module, name)) for name in members)
+
 
 class Code(object):
     """Abstract base class for the `Expression` and `Suite` classes."""
@@ -270,6 +292,7 @@
             '_lookup_name': cls.lookup_name,
             '_lookup_attr': cls.lookup_attr,
             '_lookup_item': cls.lookup_item,
+            '_star_import_patch': _star_import_patch,
             'UndefinedError': UndefinedError,
         }
     globals = classmethod(globals)
@@ -492,6 +515,16 @@
             node.doc, self.visit(node.code)
         )
 
+    def visitFrom(self, node):
+        if not has_star_import_bug or node.names != [('*', None)]:
+            # This is a Python 2.4 bug. Only if we have a broken Python
+            # version we have to apply the hack
+            return node
+        return ast.Discard(ast.CallFunc(
+            ast.Name('_star_import_patch'),
+            [ast.Name('__data__'), ast.Const(node.modname)], None, None
+        ), lineno=node.lineno)
+
     def visitFunction(self, node):
         args = []
         if hasattr(node, 'decorators'):
--- a/genshi/template/tests/eval.py
+++ b/genshi/template/tests/eval.py
@@ -571,6 +571,12 @@
         suite.execute(data)
         assert 'ifilter' in data
 
+    def test_import_star(self):
+        suite = Suite("from itertools import *")
+        data = {}
+        suite.execute(data)
+        assert 'ifilter' in data
+
     def test_for(self):
         suite = Suite("""x = []
 for i in range(3):
Copyright (C) 2012-2017 Edgewall Software