Jinja: لا يعمل FileSystemLoader مع مسارات Windows (الخطوط المائلة العكسية)

تم إنشاؤها على ٧ سبتمبر ٢٠١٧  ·  9تعليقات  ·  مصدر: pallets/jinja

سلوك متوقع

في نظام التشغيل 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

بيئتك

  • إصدار Python: 2.7.12
  • إصدار Jinja: 2.9.6

التعليق الأكثر فائدة

أعتقد أنه يجب ذكر هذه المعلومات صراحةً في الوثائق بخط عريض إذا كنت لا تنوي إصلاحها. لا يعني ذلك أنني استخدمت الخطوط المائلة العكسية عن قصد - عند إنشاء اسم الملف باستخدام بعض رموز Python الأخرى (على سبيل المثال من خلال البحث في المجلدات عن الامتدادات المناسبة) ، تحتوي السلسلة على خطوط مائلة أصلية للنظام (لذا فإن الخطوط المائلة للخلف على Windows). في هذه الحالة ، عليك استبدال الشرطات بشكل صريح ...

راجع للشغل - أنا لا أستخدم Windows ، لكني أكتب نصًا يجب أن يعمل على جميع الأنظمة الأساسية.

ال 9 كومينتر

أسماء قوالب Jinja ليست مسارات نظام ملفات (على الرغم من أنها ترتبط بمسارات نظام الملفات عند استخدام FileSystemLoader فقط). يستخدمون دائمًا خطوط مائلة للأمام ، لذلك يعمل هذا على النحو المنشود.

أعتقد أنه يجب ذكر هذه المعلومات صراحةً في الوثائق بخط عريض إذا كنت لا تنوي إصلاحها. لا يعني ذلك أنني استخدمت الخطوط المائلة العكسية عن قصد - عند إنشاء اسم الملف باستخدام بعض رموز Python الأخرى (على سبيل المثال من خلال البحث في المجلدات عن الامتدادات المناسبة) ، تحتوي السلسلة على خطوط مائلة أصلية للنظام (لذا فإن الخطوط المائلة للخلف على Windows). في هذه الحالة ، عليك استبدال الشرطات بشكل صريح ...

راجع للشغل - أنا لا أستخدم Windows ، لكني أكتب نصًا يجب أن يعمل على جميع الأنظمة الأساسية.

تضمين التغريدة
هل هذا واحد ثابت؟ يبدو أنه لا يزال يؤثر علي في عام 2019.

ما علي فعله هو استبدال كل \\ إلى / يدويًا.

هل هذا واحد ثابت؟

"إنها ليست خطأ - إنها ميزة!" (؛

هذا غريب حقا! هل يمكن تغيير هذا أو ذكره (بأحرف كبيرة) في المستندات من فضلك؟

ترحيب العلاقات العامة (للمستندات)

لقد بدأت في واحدة ، ولكن بعد ذلك وجدت هذا: 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 ترجع المسار مع '\' على النوافذ افتراضيًا. أعلم أنه سلوك صحيح بطريقة ما ، لكن الوظيفة المضمنة مثل "فتح" تقبل كلاً من الشرطة المائلة والخلفية ، لذا "أحيانًا ينجح الأمر ، وأحيانًا لا" يحدث نوعًا من الأشياء. ربما نحتاج إلى طريقة ما للتعامل مع المسارات المستقلة عن المنصات ... نوع من "اصطلاح بايثون للتعامل مع المسارات داخليًا" نوعًا من الأشياء ... أعتقد أن هذه ليست مشكلة في 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 ، وقام بتصحيح الخطأ "لم يتم العثور على القالب".

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات