Added non-babel output mode to extract_from_ast, integreated jinja2 doctests directly into the py.test suite (ugh, that's an ugly hack)
--HG--
branch : trunk
diff --git a/jinja2/ext.py b/jinja2/ext.py
index f60aade..4d68983 100644
--- a/jinja2/ext.py
+++ b/jinja2/ext.py
@@ -321,8 +321,28 @@
return nodes.Continue(lineno=token.lineno)
-def extract_from_ast(node, gettext_functions=GETTEXT_FUNCTIONS):
- """Extract localizable strings from the given template node.
+def extract_from_ast(node, gettext_functions=GETTEXT_FUNCTIONS,
+ babel_style=True):
+ """Extract localizable strings from the given template node. Per
+ default this function returns matches in babel style that means non string
+ parameters as well as keyword arguments are returned as `None`. This
+ allows Babel to figure out what you really meant if you are using
+ gettext functions that allow keyword arguments for placeholder expansion.
+ If you don't want that behavior set the `babel_style` parameter to `False`
+ which causes only strings to be returned and parameters are always stored
+ in tuples. As a consequence invalid gettext calls (calls without a single
+ string parameter or string parameters after non-string parameters) are
+ skipped.
+
+ This example explains the behavior:
+
+ >>> from jinja2 import Environment
+ >>> env = Environment()
+ >>> node = env.parse('{{ (_("foo"), _(), ngettext("foo", "bar", 42)) }}')
+ >>> list(extract_from_ast(node))
+ [(1, '_', 'foo'), (1, '_', ()), (1, 'ngettext', ('foo', 'bar', None))]
+ >>> list(extract_from_ast(node, babel_style=False))
+ [(1, '_', ('foo',)), (1, 'ngettext', ('foo', 'bar'))]
For every string found this function yields a ``(lineno, function,
message)`` tuple, where:
@@ -346,10 +366,22 @@
else:
strings.append(None)
- if len(strings) == 1:
- strings = strings[0]
+ for arg in node.kwargs:
+ strings.append(None)
+ if node.dyn_args is not None:
+ strings.append(None)
+ if node.dyn_kwargs is not None:
+ strings.append(None)
+
+ if not babel_style:
+ strings = tuple(x for x in strings if x is not None)
+ if not strings:
+ continue
else:
- strings = tuple(strings)
+ if len(strings) == 1:
+ strings = strings[0]
+ else:
+ strings = tuple(strings)
yield node.lineno, node.node.name, strings