# HG changeset patch # User cmlenz # Date 1236338747 0 # Node ID c66c83861266cd5cea7b91316a84d4ee53fc2699 # Parent f8ca33751678a51ccfea8b8de228f3d4f72bc9b4 Fix for import statements in function defs in template code blocks (#276). diff --git a/ChangeLog b/ChangeLog --- a/ChangeLog +++ b/ChangeLog @@ -16,6 +16,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/astutil.py b/genshi/template/astutil.py --- a/genshi/template/astutil.py +++ b/genshi/template/astutil.py @@ -206,6 +206,8 @@ self.visit(node.dest) if getattr(node, 'values', None): self._write(', ') + else: + self._write(' ') if getattr(node, 'values', None): self.visit(node.values[0]) for value in node.values[1:]: diff --git a/genshi/template/eval.py b/genshi/template/eval.py --- a/genshi/template/eval.py +++ b/genshi/template/eval.py @@ -485,20 +485,26 @@ self.locals = [CONSTANTS] def _extract_names(self, node): - arguments = set() + names = set() def _process(node): if isinstance(node, _ast.Name): - arguments.add(node.id) + names.add(node.id) + elif isinstance(node, _ast.alias): + names.add(node.asname or node.name) elif isinstance(node, _ast.Tuple): for elt in node.elts: _process(node) - for arg in node.args: - _process(arg) - if hasattr(node, 'vararg'): - arguments.add(node.vararg) - if hasattr(node, 'kwarg'): - arguments.add(node.kwarg) - return arguments + if hasattr(node, 'args'): + for arg in node.args: + _process(arg) + if hasattr(node, 'vararg'): + names.add(node.vararg) + if hasattr(node, 'kwarg'): + names.add(node.kwarg) + elif hasattr(node, 'names'): + for elt in node.names: + _process(elt) + return names def visit_Str(self, node): if isinstance(node.s, str): @@ -517,16 +523,25 @@ finally: self.locals.pop() + def visit_Import(self, node): + if len(self.locals) > 1: + self.locals[-1].update(self._extract_names(node)) + return ASTTransformer.visit_Import(self, node) + def visit_ImportFrom(self, node): - if not has_star_import_bug or [a.name for a in node.names] != ['*']: - # This is a Python 2.4 bug. Only if we have a broken Python - # version we have to apply the hack + if [a.name for a in node.names] == ['*']: + if has_star_import_bug: + # This is a Python 2.4 bug. Only if we have a broken Python + # version do we need to apply this hack + node = _new(_ast.Expr, _new(_ast.Call, + _new(_ast.Name, '_star_import_patch'), [ + _new(_ast.Name, '__data__'), + _new(_ast.Str, node.module) + ], (), ())) return node - return _new(_ast.Expr, _new(_ast.Call, - _new(_ast.Name, '_star_import_patch'), [ - _new(_ast.Name, '__data__'), - _new(_ast.Str, node.module) - ], (), ())) + if len(self.locals) > 1: + self.locals[-1].update(self._extract_names(node)) + return ASTTransformer.visit_ImportFrom(self, node) def visit_FunctionDef(self, node): if len(self.locals) > 1: