from hashlib import sha1
from jinja2.exceptions import TemplateNotFound
from jinja2.utils import open_if_exists, internalcode
-from jinja2._compat import string_types, iteritems
+from jinja2._compat import string_types, path_types, iteritems
def split_template_path(template):
"""
def __init__(self, searchpath, encoding='utf-8', followlinks=False):
- if isinstance(searchpath, string_types):
+ if isinstance(searchpath, path_types):
searchpath = [searchpath]
- self.searchpath = list(searchpath)
+
+ # In Python 3.5, os.path.join only supports strings, not instances
+ # of pathlib.Path. This line can be simplified to list(searchpath)
+ # when support for Python 3.5 is dropped.
+ self.searchpath = [str(path) for path in searchpath]
+
self.encoding = encoding
self.followlinks = followlinks
# create a fake module that looks for the templates in the
# path given.
mod = _TemplateModule(package_name)
- if isinstance(path, string_types):
- path = [path]
+ if isinstance(path, path_types):
+ path = [str(path)]
else:
- path = list(path)
+ path = [str(p) for p in path]
mod.__path__ = path
sys.modules[package_name] = weakref.proxy(mod,
import os
import shutil
import sys
+import time
import tempfile
import weakref
assert tmpl.render().strip() == 'BAR'
pytest.raises(TemplateNotFound, env.get_template, 'missing.html')
- def test_filesystem_loader(self, filesystem_loader):
- env = Environment(loader=filesystem_loader)
- tmpl = env.get_template('test.html')
- assert tmpl.render().strip() == 'BAR'
- tmpl = env.get_template('foo/test.html')
- assert tmpl.render().strip() == 'FOO'
- pytest.raises(TemplateNotFound, env.get_template, 'missing.html')
-
def test_filesystem_loader_overlapping_names(self, filesystem_loader):
res = os.path.dirname(filesystem_loader.searchpath[0])
t2_dir = os.path.join(res, "templates2")
pytest.raises(TemplateNotFound, split_template_path, '../foo')
+@pytest.mark.loaders
+@pytest.mark.filesystemloader
+class TestFileSystemLoader(object):
+ searchpath = os.path.dirname(os.path.abspath(__file__)) + '/res/templates'
+
+ @staticmethod
+ def _test_common(env):
+ tmpl = env.get_template('test.html')
+ assert tmpl.render().strip() == 'BAR'
+ tmpl = env.get_template('foo/test.html')
+ assert tmpl.render().strip() == 'FOO'
+ pytest.raises(TemplateNotFound, env.get_template, 'missing.html')
+
+ def test_searchpath_as_str(self):
+ filesystem_loader = loaders.FileSystemLoader(self.searchpath)
+
+ env = Environment(loader=filesystem_loader)
+ self._test_common(env)
+
+ @pytest.mark.skipif(PY2, reason='pathlib is not available in Python 2')
+ def test_searchpath_as_pathlib(self):
+ import pathlib
+ searchpath = pathlib.Path(self.searchpath)
+
+ filesystem_loader = loaders.FileSystemLoader(searchpath)
+
+ env = Environment(loader=filesystem_loader)
+ self._test_common(env)
+
+ @pytest.mark.skipif(PY2, reason='pathlib is not available in Python 2')
+ def test_searchpath_as_list_including_pathlib(self):
+ import pathlib
+ searchpath = pathlib.Path(self.searchpath)
+
+ filesystem_loader = loaders.FileSystemLoader(['/tmp/templates', searchpath])
+
+ env = Environment(loader=filesystem_loader)
+ self._test_common(env)
+
+ def test_caches_template_based_on_mtime(self):
+ filesystem_loader = loaders.FileSystemLoader(self.searchpath)
+
+ env = Environment(loader=filesystem_loader)
+ tmpl1 = env.get_template('test.html')
+ tmpl2 = env.get_template('test.html')
+ assert tmpl1 is tmpl2
+
+ os.utime(
+ os.path.join(self.searchpath, "test.html"),
+ (time.time(), time.time())
+ )
+ tmpl3 = env.get_template('test.html')
+ assert tmpl1 is not tmpl3
+
+ @pytest.mark.parametrize('encoding, expected_text', [
+ ('utf-8', u'tech'),
+ ('utf-16', u'整档'),
+ ])
+ def test_uses_specified_encoding(self, encoding, expected_text):
+ filesystem_loader = loaders.FileSystemLoader(self.searchpath, encoding=encoding)
+ env = Environment(loader=filesystem_loader)
+ tmpl = env.get_template('variable_encoding.txt')
+ assert tmpl.render().strip() == expected_text
+
+
@pytest.mark.loaders
@pytest.mark.moduleloader
class TestModuleLoader(object):
tmpl2 = self.mod_env.get_template('DICT/test.html')
assert tmpl2.render() == 'DICT_TEMPLATE'
+ @pytest.mark.skipif(PY2, reason='pathlib is not available in Python 2')
+ def test_path_as_pathlib(self, prefix_loader):
+ self.compile_down(prefix_loader)
+
+ mod_path = self.mod_env.loader.module.__path__[0]
+
+ import pathlib
+ mod_loader = loaders.ModuleLoader(pathlib.Path(mod_path))
+ self.mod_env = Environment(loader=mod_loader)
+
+ self._test_common()
+
+ @pytest.mark.skipif(PY2, reason='pathlib is not available in Python 2')
+ def test_supports_pathlib_in_list_of_paths(self, prefix_loader):
+ self.compile_down(prefix_loader)
+
+ mod_path = self.mod_env.loader.module.__path__[0]
+
+ import pathlib
+ mod_loader = loaders.ModuleLoader([
+ pathlib.Path(mod_path),
+ '/tmp/templates'
+ ])
+ self.mod_env = Environment(loader=mod_loader)
+
+ self._test_common()
+
@pytest.fixture()
def package_dir_loader(monkeypatch):