help:
@echo "Please use \`make <target>' where <target> is one of"
@echo " html to make standalone HTML files"
- @echo " pickle to make pickle files (usable by e.g. sphinx-web)"
+ @echo " pickle to make pickle files"
+ @echo " json to make JSON files"
@echo " htmlhelp to make HTML files and a HTML help project"
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@echo " changes to make an overview over all changed/added/deprecated items"
mkdir -p _build/pickle _build/doctrees
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) _build/pickle
@echo
- @echo "Build finished; now you can process the pickle files or run"
- @echo " sphinx-web _build/pickle"
- @echo "to start the sphinx-web server."
+ @echo "Build finished; now you can process the pickle files"
+
+json:
+ mkdir -p _build/json _build/doctrees
+ $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) _build/json
+ @echo
+ @echo "Build finished; now you can process the json files"
web: pickle
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:
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
>>> loader = ChoiceLoader([
... FileSystemLoader('/path/to/user/templates'),
- ... PackageLoader('myapplication')
+ ... PackageLoader('mypackage')
... ])
This is useful if you want to allow users to override builtin templates
>>> foo + 42
Traceback (most recent call last):
...
- jinja2.exceptions.UndefinedError: 'foo' is undefined
+ UndefinedError: 'foo' is undefined
"""
__slots__ = ('_undefined_hint', '_undefined_obj', '_undefined_name',
'_undefined_exception')
>>> foo + 42
Traceback (most recent call last):
...
- jinja2.exceptions.UndefinedError: 'foo' is undefined
+ UndefinedError: 'foo' is undefined
"""
__slots__ = ()
>>> str(foo)
Traceback (most recent call last):
...
- jinja2.exceptions.UndefinedError: 'foo' is undefined
+ UndefinedError: 'foo' is undefined
>>> not foo
Traceback (most recent call last):
...
- jinja2.exceptions.UndefinedError: 'foo' is undefined
+ UndefinedError: 'foo' is undefined
>>> foo + 42
Traceback (most recent call last):
...
- jinja2.exceptions.UndefinedError: 'foo' is undefined
+ UndefinedError: 'foo' is undefined
"""
__slots__ = ()
__iter__ = __unicode__ = __len__ = __nonzero__ = __eq__ = __ne__ = \
from jinja2.loaders import BaseLoader
from jinja2.exceptions import TemplateNotFound
+
try:
# This code adds support for coverage.py (see
# http://nedbatchelder.com/code/modules/coverage.html).
simple_env = Environment(trim_blocks=True, loader=loader, cache_size=0)
+class Directory(py.test.collect.Directory):
+
+ def run(self):
+ rv = super(Directory, self).run()
+ if self.fspath.basename == 'tests':
+ rv.append('doctests')
+ return rv
+
+ def join(self, name):
+ if name == 'doctests':
+ return JinjaDocTestModule(name, parent=self)
+ return super(Directory, self).join(name)
+
+
class Module(py.test.collect.Module):
def __init__(self, *args, **kwargs):
class JinjaDocTest(py.test.collect.Item):
+ def __init__(self, *args, **kwargs):
+ realmod = kwargs.pop('realmod', False)
+ super(JinjaDocTest, self).__init__(*args, **kwargs)
+ self.realmod = realmod
+
def run(self):
- mod = py.std.types.ModuleType(self.name)
- mod.__doc__ = self.obj
+ if self.realmod:
+ mod = __import__(self.name, None, None, [''])
+ else:
+ mod = py.std.types.ModuleType(self.name)
+ mod.__doc__ = self.obj
+ mod.env = self.parent.env
+ mod.MODULE = self.parent.obj
self.execute(mod)
def execute(self, mod):
- mod.env = self.parent.env
- mod.MODULE = self.parent.obj
failed, tot = py.compat.doctest.testmod(mod, verbose=True)
if failed:
py.test.fail('doctest %s: %s failed out of %s' % (
self.fspath, failed, tot))
+
+
+class JinjaDocTestModule(py.test.collect.Module):
+
+ def __init__(self, *args, **kwargs):
+ super(JinjaDocTestModule, self).__init__(*args, **kwargs)
+ self.doctest_modules = [
+ 'jinja2.environment', 'jinja2.compiler', 'jinja2.parser',
+ 'jinja2.lexer', 'jinja2.ext', 'jinja2.sandbox',
+ 'jinja2.filters', 'jinja2.tests', 'jinja2.utils',
+ 'jinja2.runtime'
+ ]
+
+ def run(self):
+ return self.doctest_modules
+
+ def join(self, name):
+ return JinjaDocTest(name, parent=self, realmod=True)