В Windows FileSystemLoader
должен разрешать пути как в стиле Windows (с \
), так и в стиле UNIX (с /
).
В Windows при использовании FileSystemLoader
происходит сбой:
jinjaEnvironment.get_template('.\source\architecture\ARM\ARMv6-M-ARMv7-M\bo
ardTemplates\ARMv6-M-ARMv7-M.metadata')
с участием
jinja2.exceptions.TemplateNotFound: .\source\architecture\ARM\ARMv6-M-ARMv7-M\bo
ardTemplates\ARMv6-M-ARMv7-M.metadata
в то время как этот jinjaEnvironment.get_template('.\source\architecture\ARM\ARMv6-M-ARMv7-M\bo
ardTemplates\ARMv6-M-ARMv7-M.metadata'.replace('\\', '/'))
работает отлично.
Traceback (most recent call last):
File "./scripts/generateBoard.py", line 186, in <module>
metadata = jinjaEnvironment.get_template(metadataFile).render(dictionary = d
ictionary)
File "C:\Python27\lib\site-packages\jinja2\environment.py", line 830, in get_t
emplate
return self._load_template(name, self.make_globals(globals))
File "C:\Python27\lib\site-packages\jinja2\environment.py", line 804, in _load
_template
template = self.loader.load(self, name, globals)
File "C:\Python27\lib\site-packages\jinja2\loaders.py", line 113, in load
source, filename, uptodate = self.get_source(environment, name)
File "C:\Python27\lib\site-packages\jinja2\loaders.py", line 168, in get_sourc
e
pieces = split_template_path(template)
File "C:\Python27\lib\site-packages\jinja2\loaders.py", line 31, in split_temp
late_path
raise TemplateNotFound(template)
jinja2.exceptions.TemplateNotFound: .\source\architecture\ARM\ARMv6-M-ARMv7-M\bo
ardTemplates\ARMv6-M-ARMv7-M.metadata
Имена шаблонов Jinja не являются путями файловой системы (даже если они сопоставляются с путями файловой системы при использовании только FileSystemLoader). Они всегда используют косую черту, так что это работает по назначению.
Я думаю, что эта информация должна быть явно указана в документации жирным шрифтом, если вы не собираетесь ее исправлять. Дело не в том, что я специально использовал обратную косую черту - при создании имени файла с использованием какого-либо другого кода Python (например, путем поиска в папках соответствующих расширений) строка имеет родные системные косые черты (такие как обратные косые черты в Windows). В этом случае вы должны явно заменить косую черту...
Кстати, я не использую Windows, но пишу скрипт, который должен работать на всех платформах.
@ФреддиШопен
Этот фиксированный? кажется, все еще влияет на меня в 2019 году.
Что мне нужно сделать, так это вручную заменить все \\
на /
.
Этот фиксированный?
"Это не баг - это фича!" (;
Это действительно странно! Можно ли это изменить или упомянуть (большими буквами) в документах, пожалуйста?
PR-приветствие (для документов)
Я начал с одного, но потом нашел это: https://github.com/pallets/jinja/blob/master/jinja2/loaders.py#L43 -L61
A very basic example for a loader that looks up templates on the file
system could look like this::
from jinja2 import BaseLoader, TemplateNotFound
from os.path import join, exists, getmtime
class MyLoader(BaseLoader):
def __init__(self, path):
self.path = path
def get_source(self, environment, template):
path = join(self.path, template)
if not exists(path):
raise TemplateNotFound(template)
mtime = getmtime(path)
with file(path) as f:
source = f.read().decode('utf-8')
return source, path, lambda: mtime == getmtime(path)
В документах прямо говорится, что следует/можно использовать os.path.join. Может быть, проблема более уместна?
Настоящая проблема заключается в том, что модуль пути python по умолчанию возвращает путь с «\» в окнах. Я знаю, что это правильное поведение, но встроенная функция, такая как «открыть», принимает как косую, так и обратную косую черту, поэтому «иногда это работает, иногда — нет». Вероятно, нам нужен какой-то способ обработки путей, независимых от платформ... своего рода "соглашение Python для внутренней обработки путей"... Я думаю, что это не проблема jinja2 (это проблема исторического соглашения между Unix и Windows, и это кажется вечным), но приветствуются некоторые «заголовки» в стартовых документах.
Основная проблема заключается в том, что «путь» шаблона на самом деле не является путем ОС, а должен содержать только разделители «/». Но в loaders.get_source() self.searchpath также считает, что разделителем путей всегда является «/».
Пути шаблонов не следует изменять, чтобы они были фактическими путями ОС, потому что, по-видимому, есть и другие места, где используется это каноническое предположение.
Решение состоит в том, чтобы изменить как шаблон, так и путь поиска, чтобы они содержали фактические разделители путей ОС в той точке, где пути ОС необходимы:
def get_source(self, environment, template):
_searchpaths = self.searchpath
if path.sep != '/':
template = template.replace('/', path.sep)
_searchpaths = [p.replace('/', path.sep) for p in self.searchpath]
pieces = os.path.split(template)
for searchpath in _searchpaths:
# Existing code continues here ...
Я кратко протестировал этот код в Windows 10/Python 2.7, и он исправил мою ошибку «Шаблон не найден».
Самый полезный комментарий
Я думаю, что эта информация должна быть явно указана в документации жирным шрифтом, если вы не собираетесь ее исправлять. Дело не в том, что я специально использовал обратную косую черту - при создании имени файла с использованием какого-либо другого кода Python (например, путем поиска в папках соответствующих расширений) строка имеет родные системные косые черты (такие как обратные косые черты в Windows). В этом случае вы должны явно заменить косую черту...
Кстати, я не использую Windows, но пишу скрипт, который должен работать на всех платформах.