]> git.ipfire.org Git - thirdparty/jinja.git/commitdiff
use fspath instead of str 1064/head
authorDavid Lord <davidism@gmail.com>
Mon, 21 Oct 2019 14:00:25 +0000 (07:00 -0700)
committerDavid Lord <davidism@gmail.com>
Mon, 21 Oct 2019 14:37:26 +0000 (07:37 -0700)
CHANGES.rst
jinja2/_compat.py
jinja2/loaders.py

index 45eab845a6b0371985b78940eeee667af59bb790..bc3114def59b800083df6d352a84261d342bd6a0 100644 (file)
@@ -49,9 +49,9 @@ Unreleased
     :pr:`993`
 -   ``PackageLoader`` doesn't depend on setuptools or pkg_resources.
     :issue:`970`
--   Allow passing ``pathlib.Path`` as the search path in
-    :class:`~loader.FileSystemLoader` and
-    :class:`~loader.ModuleLoader`. :issue:`870`
+-   Support :class:`os.PathLike` objects in
+    :class:`~loader.FileSystemLoader` and :class:`~loader.ModuleLoader`.
+    :issue:`870`
 
 
 Version 2.10.3
index 65f047e3fdb8b1fde55b82141f505e6e8ffa3cfc..814d2246e001ec6ee23ca9e6cae7c19e8b5cbe75 100644 (file)
@@ -24,9 +24,6 @@ if not PY2:
     string_types = (str,)
     integer_types = (int,)
 
-    import pathlib
-    path_types = (str, pathlib.PurePath)
-
     iterkeys = lambda d: iter(d.keys())
     itervalues = lambda d: iter(d.values())
     iteritems = lambda d: iter(d.items())
@@ -56,8 +53,6 @@ else:
     string_types = (str, unicode)
     integer_types = (int, long)
 
-    path_types = string_types
-
     iterkeys = lambda d: d.iterkeys()
     itervalues = lambda d: d.itervalues()
     iteritems = lambda d: d.iteritems()
@@ -108,3 +103,22 @@ try:
     from collections import abc
 except ImportError:
     import collections as abc
+
+
+try:
+    from os import fspath
+except ImportError:
+    try:
+        from pathlib import PurePath
+    except ImportError:
+        PurePath = None
+
+    def fspath(path):
+        if hasattr(path, "__fspath__"):
+            return path.__fspath__()
+
+        # Python 3.5 doesn't have __fspath__ yet, use str.
+        if PurePath is not None and isinstance(path, PurePath):
+            return str(path)
+
+        return path
index 40118fd5e0af099bb55555cc39c910bde49dc749..3101bc3ad43a8e378c012d3595e6b8b80fd071be 100644 (file)
@@ -17,7 +17,7 @@ from os import path
 from hashlib import sha1
 from jinja2.exceptions import TemplateNotFound
 from jinja2.utils import open_if_exists, internalcode
-from jinja2._compat import string_types, path_types, iteritems
+from jinja2._compat import string_types, iteritems, fspath, abc
 
 
 def split_template_path(template):
@@ -154,18 +154,20 @@ class FileSystemLoader(BaseLoader):
 
     >>> loader = FileSystemLoader('/path/to/templates', followlinks=True)
 
-    .. versionchanged:: 2.8+
-       The *followlinks* parameter was added.
+    .. versionchanged:: 2.8
+       The ``followlinks`` parameter was added.
     """
 
     def __init__(self, searchpath, encoding='utf-8', followlinks=False):
-        if isinstance(searchpath, path_types):
+        if (
+            not isinstance(searchpath, abc.Iterable)
+            or isinstance(searchpath, string_types)
+        ):
             searchpath = [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]
+        # In Python 3.5, os.path.join doesn't support Path. This can be
+        # simplified to list(searchpath) when Python 3.5 is dropped.
+        self.searchpath = [fspath(p) for p in searchpath]
 
         self.encoding = encoding
         self.followlinks = followlinks
@@ -489,11 +491,14 @@ class ModuleLoader(BaseLoader):
         # create a fake module that looks for the templates in the
         # path given.
         mod = _TemplateModule(package_name)
-        if isinstance(path, path_types):
-            path = [str(path)]
-        else:
-            path = [str(p) for p in path]
-        mod.__path__ = path
+
+        if (
+            not isinstance(path, abc.Iterable)
+            or isinstance(path, string_types)
+        ):
+            path = [path]
+
+        mod.__path__ = [fspath(p) for p in path]
 
         sys.modules[package_name] = weakref.proxy(mod,
             lambda x: sys.modules.pop(package_name, None))