Mercurial > genshi > mirror
changeset 165:54a4be707664 trunk
Fix handling of keyword arguments in `py:def` directive. Thanks to Christian Boos for reporting the problem and providing the basic patch for this change.
author | cmlenz |
---|---|
date | Thu, 17 Aug 2006 14:02:58 +0000 |
parents | 1f6cb675a66c |
children | d43f50402cf2 |
files | markup/eval.py markup/template.py markup/tests/template.py |
diffstat | 3 files changed, 33 insertions(+), 12 deletions(-) [+] |
line wrap: on
line diff
--- a/markup/eval.py +++ b/markup/eval.py @@ -65,12 +65,15 @@ __slots__ = ['source', 'code'] def __init__(self, source, filename=None, lineno=-1): - """Create the expression. - - @param source: the expression as string - """ - self.source = source - self.code = _compile(self, filename, lineno) + if isinstance(source, basestring): + self.source = source + self.code = _compile(parse(source, 'eval'), source, + filename=filename, lineno=lineno) + else: + assert isinstance(source, ast.Node) + self.source = '?' + self.code = _compile(ast.Expression(source), filename=filename, + lineno=lineno) def __repr__(self): return '<Expression "%s">' % self.source @@ -92,8 +95,8 @@ return retval -def _compile(expr, filename=None, lineno=-1): - tree = ExpressionASTTransformer().visit(parse(expr.source, 'eval')) +def _compile(node, source=None, filename=None, lineno=-1): + tree = ExpressionASTTransformer().visit(node) if isinstance(filename, unicode): # unicode file names not allowed for code objects filename = filename.encode('utf-8', 'replace') @@ -111,8 +114,9 @@ # clone the code object while adjusting the line number return new.code(0, code.co_nlocals, code.co_stacksize, code.co_flags | 0x0040, code.co_code, code.co_consts, - code.co_names, code.co_varnames, filename, repr(expr), - lineno, code.co_lnotab, (), ()) + code.co_names, code.co_varnames, filename, + '<Expression "%s">' % (str(source) or '?'), lineno, + code.co_lnotab, (), ()) def _lookup_name(data, name, locals_=None): val = None
--- a/markup/template.py +++ b/markup/template.py @@ -306,7 +306,8 @@ for arg in ast.args: if isinstance(arg, compiler.ast.Keyword): self.args.append(arg.name) - self.defaults[arg.name] = arg.expr.value + self.defaults[arg.name] = Expression(arg.expr, filename, + lineno) else: self.args.append(arg.name) else: @@ -322,7 +323,11 @@ if args: scope[name] = args.pop(0) else: - scope[name] = kwargs.pop(name, self.defaults.get(name)) + if name in kwargs: + val = kwargs.pop(name) + else: + val = self.defaults.get(name).evaluate(ctxt) + scope[name] = val ctxt.push(scope) for event in _apply_directives(stream, ctxt, directives): yield event
--- a/markup/tests/template.py +++ b/markup/tests/template.py @@ -203,6 +203,18 @@ <strong>foo</strong> </doc>""", str(tmpl.generate(semantic=True))) + def test_function_with_default_arg(self): + """ + Verify that keyword arguments work with `py:def` directives. + """ + tmpl = Template("""<doc xmlns:py="http://markup.edgewall.org/"> + <b py:def="echo(what, bold=False)" py:strip="not bold">${what}</b> + ${echo('foo')} + </doc>""") + self.assertEqual("""<doc> + foo + </doc>""", str(tmpl.generate())) + class ForDirectiveTestCase(unittest.TestCase): """Tests for the `py:for` template directive."""