template_dirs returns a mixed list of string and posixpath

my question is does providing a mixed type list expected behavior? from looking at the jinja2 consumer it seems like they had to work this result. does stuff like this create performance issues.

getting a list of template directories from django/template/backends/base.py via
the BaseEngine.template_dirs() method. BaseEngine initializes internal property dirs as a list of
strings from the configuration. template_dirs returns that list with an appended list of Path objects. effectively creating a tuple of (string, path, path …)

  # Utility methods: they are provided to minimize code duplication and
    #                  security issues in third-party backends.

    @cached_property
    def template_dirs(self):
        """
        Return a list of directories to search for templates.
        """
        # Immutable return value because it's cached and shared by callers.
        template_dirs = tuple(self.dirs)
        if self.app_dirs:
            template_dirs += get_app_template_dirs(self.app_dirname)
        return template_dirs

this mixed tuple value is passed to jinja2 in the FileSystemLoader constructor. the typechecking
is looking for this. searchpath: t.Union[str, os.PathLike, t.Sequence[t.Union[str, os.PathLike]]], then jinja2 applies self.searchpath = [os.fspath(p) for p in searchpath] Finally jinja2 casts it back to paths filename = os.path.join(searchpath, *pieces)

just had to document this before moving on.

Yes - since PEP 519 – Adding a file system path protocol | peps.python.org it’s conventional to support str | PathLike as the type for file system paths.

Thanks, so when getting a list of paths where it can be a mixed type. use the fspath to convert to string
and throw exceptions if it isn’t path like.

[os.fspath(p) for p in searchpath]

Yup! That’s the ticket.

1 Like