skip template with same name as directory

When using multiple paths with FileSystemLoader, a template with the
same name as a directory will not prevent loading a template in the
directory.
This commit is contained in:
David Lord 2019-10-13 06:40:54 -07:00
parent 0687adfa86
commit aaf13a231c
No known key found for this signature in database
GPG Key ID: 7A1C87E3F5BC42A8
4 changed files with 23 additions and 9 deletions

View File

@ -1,7 +1,7 @@
.. currentmodule:: jinja2
Version 2.11
------------
Version 2.11.0
--------------
Unreleased
@ -37,6 +37,8 @@ Unreleased
- The environment's ``finalize`` function is only applied to the
output of expressions (constant or not), not static template data.
:issue:`63`
- When providing multiple paths to ``FileSystemLoader``, a template
can have the same name as a directory. :issue:`821`
Version 2.10.3

View File

@ -8,9 +8,9 @@
:copyright: (c) 2017 by the Jinja Team.
:license: BSD, see LICENSE for more details.
"""
import os
import re
import json
import errno
import warnings
from collections import deque
from threading import Lock
@ -147,13 +147,12 @@ def import_string(import_name, silent=False):
def open_if_exists(filename, mode='rb'):
"""Returns a file descriptor for the filename if that file exists,
otherwise `None`.
otherwise ``None``.
"""
try:
return open(filename, mode)
except IOError as e:
if e.errno not in (errno.ENOENT, errno.EISDIR, errno.EINVAL):
raise
if not os.path.isfile(filename):
return None
return open(filename, mode)
def object_type_repr(obj):

2
tests/res/templates2/foo Normal file
View File

@ -0,0 +1,2 @@
Looks like the start of templates/foo/test.html
Tested by test_filesystem_loader_overlapping_names

View File

@ -44,6 +44,17 @@ class TestLoaders(object):
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")
# Make "foo" show up before "foo/test.html".
filesystem_loader.searchpath.insert(0, t2_dir)
e = Environment(loader=filesystem_loader)
e.get_template("foo")
# This would raise NotADirectoryError if "t2/foo" wasn't skipped.
e.get_template("foo/test.html")
def test_choice_loader(self, choice_loader):
env = Environment(loader=choice_loader)
tmpl = env.get_template('justdict.html')