# HG changeset patch # User cmlenz # Date 1236340387 0 # Node ID a134e21a8f44354224a66e8e35529ecb2cba83d5 # Parent 9b1f8f93d2bf1356615ef90365e3ebe6b20abe5b Ported [1008] and [1009] to 0.5.x branch. diff --git a/ChangeLog b/ChangeLog --- a/ChangeLog +++ b/ChangeLog @@ -9,6 +9,9 @@ * `for` loops in template code blocks no longer establish their own locals scope, meaning you can now access variables assigned in the loop outside of the loop, just as you can in regular Python code (ticket #259). + * Import statements inside function definitions in template code blocks no + longer result in an UndefinedError when the imported name is accessed + (ticket #276). Version 0.5.1 diff --git a/genshi/template/eval.py b/genshi/template/eval.py --- a/genshi/template/eval.py +++ b/genshi/template/eval.py @@ -595,6 +595,9 @@ self.visit(node.else_) ) + def visitImport(self, node): + return self._clone(node, node.names) + def _visitPrint(self, node): return self._clone(node, [self.visit(x) for x in node.nodes], self.visit(node.dest) @@ -759,6 +762,12 @@ finally: self.locals.pop() + def visitFrom(self, node): + if node.names != [('*', None)]: + if len(self.locals) > 1: + self.locals[-1].update([n[1] or n[0] for n in node.names]) + return ASTTransformer.visitFrom(self, node) + def visitFunction(self, node): if len(self.locals) > 1: self.locals[-1].add(node.name) @@ -775,6 +784,11 @@ finally: self.locals.pop() + def visitImport(self, node): + if len(self.locals) > 1: + self.locals[-1].update([n.asname or n.name for n in node.names]) + return ASTTransformer.visitImport(self, node) + def visitLambda(self, node): self.locals.append(set(flatten(node.argnames))) try: diff --git a/genshi/template/tests/eval.py b/genshi/template/tests/eval.py --- a/genshi/template/tests/eval.py +++ b/genshi/template/tests/eval.py @@ -572,6 +572,16 @@ suite.execute(_ctxt2dict(data)) assert 'ifilter' in data + def test_import_in_def(self): + suite = Suite("""def fun(): + from itertools import ifilter + return ifilter(None, xrange(3)) +""") + data = Context() + suite.execute(data) + assert 'ifilter' not in data + self.assertEqual([1, 2], list(data['fun']())) + def test_for(self): suite = Suite("""x = [] for i in range(3):