From 12cf076118570eebbff08c6b3090e0d4798447a1 Mon Sep 17 00:00:00 2001 From: cyfraeviolae Date: Wed, 3 Apr 2024 03:17:55 -0400 Subject: no venv --- .../lib/python3.11/site-packages/jinja2/loaders.py | 661 --------------------- 1 file changed, 661 deletions(-) delete mode 100644 venv/lib/python3.11/site-packages/jinja2/loaders.py (limited to 'venv/lib/python3.11/site-packages/jinja2/loaders.py') diff --git a/venv/lib/python3.11/site-packages/jinja2/loaders.py b/venv/lib/python3.11/site-packages/jinja2/loaders.py deleted file mode 100644 index 32f3a74..0000000 --- a/venv/lib/python3.11/site-packages/jinja2/loaders.py +++ /dev/null @@ -1,661 +0,0 @@ -"""API and implementations for loading templates from different data -sources. -""" -import importlib.util -import os -import posixpath -import sys -import typing as t -import weakref -import zipimport -from collections import abc -from hashlib import sha1 -from importlib import import_module -from types import ModuleType - -from .exceptions import TemplateNotFound -from .utils import internalcode - -if t.TYPE_CHECKING: - from .environment import Environment - from .environment import Template - - -def split_template_path(template: str) -> t.List[str]: - """Split a path into segments and perform a sanity check. If it detects - '..' in the path it will raise a `TemplateNotFound` error. - """ - pieces = [] - for piece in template.split("/"): - if ( - os.path.sep in piece - or (os.path.altsep and os.path.altsep in piece) - or piece == os.path.pardir - ): - raise TemplateNotFound(template) - elif piece and piece != ".": - pieces.append(piece) - return pieces - - -class BaseLoader: - """Baseclass for all loaders. Subclass this and override `get_source` to - implement a custom loading mechanism. The environment provides a - `get_template` method that calls the loader's `load` method to get the - :class:`Template` object. - - 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 open(path) as f: - source = f.read() - return source, path, lambda: mtime == getmtime(path) - """ - - #: if set to `False` it indicates that the loader cannot provide access - #: to the source of templates. - #: - #: .. versionadded:: 2.4 - has_source_access = True - - def get_source( - self, environment: "Environment", template: str - ) -> t.Tuple[str, t.Optional[str], t.Optional[t.Callable[[], bool]]]: - """Get the template source, filename and reload helper for a template. - It's passed the environment and template name and has to return a - tuple in the form ``(source, filename, uptodate)`` or raise a - `TemplateNotFound` error if it can't locate the template. - - The source part of the returned tuple must be the source of the - template as a string. The filename should be the name of the - file on the filesystem if it was loaded from there, otherwise - ``None``. The filename is used by Python for the tracebacks - if no loader extension is used. - - The last item in the tuple is the `uptodate` function. If auto - reloading is enabled it's always called to check if the template - changed. No arguments are passed so the function must store the - old state somewhere (for example in a closure). If it returns `False` - the template will be reloaded. - """ - if not self.has_source_access: - raise RuntimeError( - f"{type(self).__name__} cannot provide access to the source" - ) - raise TemplateNotFound(template) - - def list_templates(self) -> t.List[str]: - """Iterates over all templates. If the loader does not support that - it should raise a :exc:`TypeError` which is the default behavior. - """ - raise TypeError("this loader cannot iterate over all templates") - - @internalcode - def load( - self, - environment: "Environment", - name: str, - globals: t.Optional[t.MutableMapping[str, t.Any]] = None, - ) -> "Template": - """Loads a template. This method looks up the template in the cache - or loads one by calling :meth:`get_source`. Subclasses should not - override this method as loaders working on collections of other - loaders (such as :class:`PrefixLoader` or :class:`ChoiceLoader`) - will not call this method but `get_source` directly. - """ - code = None - if globals is None: - globals = {} - - # first we try to get the source for this template together - # with the filename and the uptodate function. - source, filename, uptodate = self.get_source(environment, name) - - # try to load the code from the bytecode cache if there is a - # bytecode cache configured. - bcc = environment.bytecode_cache - if bcc is not None: - bucket = bcc.get_bucket(environment, name, filename, source) - code = bucket.code - - # if we don't have code so far (not cached, no longer up to - # date) etc. we compile the template - if code is None: - code = environment.compile(source, name, filename) - - # if the bytecode cache is available and the bucket doesn't - # have a code so far, we give the bucket the new code and put - # it back to the bytecode cache. - if bcc is not None and bucket.code is None: - bucket.code = code - bcc.set_bucket(bucket) - - return environment.template_class.from_code( - environment, code, globals, uptodate - ) - - -class FileSystemLoader(BaseLoader): - """Load templates from a directory in the file system. - - The path can be relative or absolute. Relative paths are relative to - the current working directory. - - .. code-block:: python - - loader = FileSystemLoader("templates") - - A list of paths can be given. The directories will be searched in - order, stopping at the first matching template. - - .. code-block:: python - - loader = FileSystemLoader(["/override/templates", "/default/templates"]) - - :param searchpath: A path, or list of paths, to the directory that - contains the templates. - :param encoding: Use this encoding to read the text from template - files. - :param followlinks: Follow symbolic links in the path. - - .. versionchanged:: 2.8 - Added the ``followlinks`` parameter. - """ - - def __init__( - self, - searchpath: t.Union[str, os.PathLike, t.Sequence[t.Union[str, os.PathLike]]], - encoding: str = "utf-8", - followlinks: bool = False, - ) -> None: - if not isinstance(searchpath, abc.Iterable) or isinstance(searchpath, str): - searchpath = [searchpath] - - self.searchpath = [os.fspath(p) for p in searchpath] - self.encoding = encoding - self.followlinks = followlinks - - def get_source( - self, environment: "Environment", template: str - ) -> t.Tuple[str, str, t.Callable[[], bool]]: - pieces = split_template_path(template) - - for searchpath in self.searchpath: - # Use posixpath even on Windows to avoid "drive:" or UNC - # segments breaking out of the search directory. - filename = posixpath.join(searchpath, *pieces) - - if os.path.isfile(filename): - break - else: - raise TemplateNotFound(template) - - with open(filename, encoding=self.encoding) as f: - contents = f.read() - - mtime = os.path.getmtime(filename) - - def uptodate() -> bool: - try: - return os.path.getmtime(filename) == mtime - except OSError: - return False - - # Use normpath to convert Windows altsep to sep. - return contents, os.path.normpath(filename), uptodate - - def list_templates(self) -> t.List[str]: - found = set() - for searchpath in self.searchpath: - walk_dir = os.walk(searchpath, followlinks=self.followlinks) - for dirpath, _, filenames in walk_dir: - for filename in filenames: - template = ( - os.path.join(dirpath, filename)[len(searchpath) :] - .strip(os.path.sep) - .replace(os.path.sep, "/") - ) - if template[:2] == "./": - template = template[2:] - if template not in found: - found.add(template) - return sorted(found) - - -class PackageLoader(BaseLoader): - """Load templates from a directory in a Python package. - - :param package_name: Import name of the package that contains the - template directory. - :param package_path: Directory within the imported package that - contains the templates. - :param encoding: Encoding of template files. - - The following example looks up templates in the ``pages`` directory - within the ``project.ui`` package. - - .. code-block:: python - - loader = PackageLoader("project.ui", "pages") - - Only packages installed as directories (standard pip behavior) or - zip/egg files (less common) are supported. The Python API for - introspecting data in packages is too limited to support other - installation methods the way this loader requires. - - There is limited support for :pep:`420` namespace packages. The - template directory is assumed to only be in one namespace - contributor. Zip files contributing to a namespace are not - supported. - - .. versionchanged:: 3.0 - No longer uses ``setuptools`` as a dependency. - - .. versionchanged:: 3.0 - Limited PEP 420 namespace package support. - """ - - def __init__( - self, - package_name: str, - package_path: "str" = "templates", - encoding: str = "utf-8", - ) -> None: - package_path = os.path.normpath(package_path).rstrip(os.path.sep) - - # normpath preserves ".", which isn't valid in zip paths. - if package_path == os.path.curdir: - package_path = "" - elif package_path[:2] == os.path.curdir + os.path.sep: - package_path = package_path[2:] - - self.package_path = package_path - self.package_name = package_name - self.encoding = encoding - - # Make sure the package exists. This also makes namespace - # packages work, otherwise get_loader returns None. - import_module(package_name) - spec = importlib.util.find_spec(package_name) - assert spec is not None, "An import spec was not found for the package." - loader = spec.loader - assert loader is not None, "A loader was not found for the package." - self._loader = loader - self._archive = None - template_root = None - - if isinstance(loader, zipimport.zipimporter): - self._archive = loader.archive - pkgdir = next(iter(spec.submodule_search_locations)) # type: ignore - template_root = os.path.join(pkgdir, package_path).rstrip(os.path.sep) - else: - roots: t.List[str] = [] - - # One element for regular packages, multiple for namespace - # packages, or None for single module file. - if spec.submodule_search_locations: - roots.extend(spec.submodule_search_locations) - # A single module file, use the parent directory instead. - elif spec.origin is not None: - roots.append(os.path.dirname(spec.origin)) - - for root in roots: - root = os.path.join(root, package_path) - - if os.path.isdir(root): - template_root = root - break - - if template_root is None: - raise ValueError( - f"The {package_name!r} package was not installed in a" - " way that PackageLoader understands." - ) - - self._template_root = template_root - - def get_source( - self, environment: "Environment", template: str - ) -> t.Tuple[str, str, t.Optional[t.Callable[[], bool]]]: - # Use posixpath even on Windows to avoid "drive:" or UNC - # segments breaking out of the search directory. Use normpath to - # convert Windows altsep to sep. - p = os.path.normpath( - posixpath.join(self._template_root, *split_template_path(template)) - ) - up_to_date: t.Optional[t.Callable[[], bool]] - - if self._archive is None: - # Package is a directory. - if not os.path.isfile(p): - raise TemplateNotFound(template) - - with open(p, "rb") as f: - source = f.read() - - mtime = os.path.getmtime(p) - - def up_to_date() -> bool: - return os.path.isfile(p) and os.path.getmtime(p) == mtime - - else: - # Package is a zip file. - try: - source = self._loader.get_data(p) # type: ignore - except OSError as e: - raise TemplateNotFound(template) from e - - # Could use the zip's mtime for all template mtimes, but - # would need to safely reload the module if it's out of - # date, so just report it as always current. - up_to_date = None - - return source.decode(self.encoding), p, up_to_date - - def list_templates(self) -> t.List[str]: - results: t.List[str] = [] - - if self._archive is None: - # Package is a directory. - offset = len(self._template_root) - - for dirpath, _, filenames in os.walk(self._template_root): - dirpath = dirpath[offset:].lstrip(os.path.sep) - results.extend( - os.path.join(dirpath, name).replace(os.path.sep, "/") - for name in filenames - ) - else: - if not hasattr(self._loader, "_files"): - raise TypeError( - "This zip import does not have the required" - " metadata to list templates." - ) - - # Package is a zip file. - prefix = ( - self._template_root[len(self._archive) :].lstrip(os.path.sep) - + os.path.sep - ) - offset = len(prefix) - - for name in self._loader._files.keys(): - # Find names under the templates directory that aren't directories. - if name.startswith(prefix) and name[-1] != os.path.sep: - results.append(name[offset:].replace(os.path.sep, "/")) - - results.sort() - return results - - -class DictLoader(BaseLoader): - """Loads a template from a Python dict mapping template names to - template source. This loader is useful for unittesting: - - >>> loader = DictLoader({'index.html': 'source here'}) - - Because auto reloading is rarely useful this is disabled per default. - """ - - def __init__(self, mapping: t.Mapping[str, str]) -> None: - self.mapping = mapping - - def get_source( - self, environment: "Environment", template: str - ) -> t.Tuple[str, None, t.Callable[[], bool]]: - if template in self.mapping: - source = self.mapping[template] - return source, None, lambda: source == self.mapping.get(template) - raise TemplateNotFound(template) - - def list_templates(self) -> t.List[str]: - return sorted(self.mapping) - - -class FunctionLoader(BaseLoader): - """A loader that is passed a function which does the loading. The - function receives the name of the template and has to return either - a string with the template source, a tuple in the form ``(source, - filename, uptodatefunc)`` or `None` if the template does not exist. - - >>> def load_template(name): - ... if name == 'index.html': - ... return '...' - ... - >>> loader = FunctionLoader(load_template) - - The `uptodatefunc` is a function that is called if autoreload is enabled - and has to return `True` if the template is still up to date. For more - details have a look at :meth:`BaseLoader.get_source` which has the same - return value. - """ - - def __init__( - self, - load_func: t.Callable[ - [str], - t.Optional[ - t.Union[ - str, t.Tuple[str, t.Optional[str], t.Optional[t.Callable[[], bool]]] - ] - ], - ], - ) -> None: - self.load_func = load_func - - def get_source( - self, environment: "Environment", template: str - ) -> t.Tuple[str, t.Optional[str], t.Optional[t.Callable[[], bool]]]: - rv = self.load_func(template) - - if rv is None: - raise TemplateNotFound(template) - - if isinstance(rv, str): - return rv, None, None - - return rv - - -class PrefixLoader(BaseLoader): - """A loader that is passed a dict of loaders where each loader is bound - to a prefix. The prefix is delimited from the template by a slash per - default, which can be changed by setting the `delimiter` argument to - something else:: - - loader = PrefixLoader({ - 'app1': PackageLoader('mypackage.app1'), - 'app2': PackageLoader('mypackage.app2') - }) - - By loading ``'app1/index.html'`` the file from the app1 package is loaded, - by loading ``'app2/index.html'`` the file from the second. - """ - - def __init__( - self, mapping: t.Mapping[str, BaseLoader], delimiter: str = "/" - ) -> None: - self.mapping = mapping - self.delimiter = delimiter - - def get_loader(self, template: str) -> t.Tuple[BaseLoader, str]: - try: - prefix, name = template.split(self.delimiter, 1) - loader = self.mapping[prefix] - except (ValueError, KeyError) as e: - raise TemplateNotFound(template) from e - return loader, name - - def get_source( - self, environment: "Environment", template: str - ) -> t.Tuple[str, t.Optional[str], t.Optional[t.Callable[[], bool]]]: - loader, name = self.get_loader(template) - try: - return loader.get_source(environment, name) - except TemplateNotFound as e: - # re-raise the exception with the correct filename here. - # (the one that includes the prefix) - raise TemplateNotFound(template) from e - - @internalcode - def load( - self, - environment: "Environment", - name: str, - globals: t.Optional[t.MutableMapping[str, t.Any]] = None, - ) -> "Template": - loader, local_name = self.get_loader(name) - try: - return loader.load(environment, local_name, globals) - except TemplateNotFound as e: - # re-raise the exception with the correct filename here. - # (the one that includes the prefix) - raise TemplateNotFound(name) from e - - def list_templates(self) -> t.List[str]: - result = [] - for prefix, loader in self.mapping.items(): - for template in loader.list_templates(): - result.append(prefix + self.delimiter + template) - return result - - -class ChoiceLoader(BaseLoader): - """This loader works like the `PrefixLoader` just that no prefix is - specified. If a template could not be found by one loader the next one - is tried. - - >>> loader = ChoiceLoader([ - ... FileSystemLoader('/path/to/user/templates'), - ... FileSystemLoader('/path/to/system/templates') - ... ]) - - This is useful if you want to allow users to override builtin templates - from a different location. - """ - - def __init__(self, loaders: t.Sequence[BaseLoader]) -> None: - self.loaders = loaders - - def get_source( - self, environment: "Environment", template: str - ) -> t.Tuple[str, t.Optional[str], t.Optional[t.Callable[[], bool]]]: - for loader in self.loaders: - try: - return loader.get_source(environment, template) - except TemplateNotFound: - pass - raise TemplateNotFound(template) - - @internalcode - def load( - self, - environment: "Environment", - name: str, - globals: t.Optional[t.MutableMapping[str, t.Any]] = None, - ) -> "Template": - for loader in self.loaders: - try: - return loader.load(environment, name, globals) - except TemplateNotFound: - pass - raise TemplateNotFound(name) - - def list_templates(self) -> t.List[str]: - found = set() - for loader in self.loaders: - found.update(loader.list_templates()) - return sorted(found) - - -class _TemplateModule(ModuleType): - """Like a normal module but with support for weak references""" - - -class ModuleLoader(BaseLoader): - """This loader loads templates from precompiled templates. - - Example usage: - - >>> loader = ChoiceLoader([ - ... ModuleLoader('/path/to/compiled/templates'), - ... FileSystemLoader('/path/to/templates') - ... ]) - - Templates can be precompiled with :meth:`Environment.compile_templates`. - """ - - has_source_access = False - - def __init__( - self, path: t.Union[str, os.PathLike, t.Sequence[t.Union[str, os.PathLike]]] - ) -> None: - package_name = f"_jinja2_module_templates_{id(self):x}" - - # create a fake module that looks for the templates in the - # path given. - mod = _TemplateModule(package_name) - - if not isinstance(path, abc.Iterable) or isinstance(path, str): - path = [path] - - mod.__path__ = [os.fspath(p) for p in path] - - sys.modules[package_name] = weakref.proxy( - mod, lambda x: sys.modules.pop(package_name, None) - ) - - # the only strong reference, the sys.modules entry is weak - # so that the garbage collector can remove it once the - # loader that created it goes out of business. - self.module = mod - self.package_name = package_name - - @staticmethod - def get_template_key(name: str) -> str: - return "tmpl_" + sha1(name.encode("utf-8")).hexdigest() - - @staticmethod - def get_module_filename(name: str) -> str: - return ModuleLoader.get_template_key(name) + ".py" - - @internalcode - def load( - self, - environment: "Environment", - name: str, - globals: t.Optional[t.MutableMapping[str, t.Any]] = None, - ) -> "Template": - key = self.get_template_key(name) - module = f"{self.package_name}.{key}" - mod = getattr(self.module, module, None) - - if mod is None: - try: - mod = __import__(module, None, None, ["root"]) - except ImportError as e: - raise TemplateNotFound(name) from e - - # remove the entry from sys.modules, we only want the attribute - # on the module object we have stored on the loader. - sys.modules.pop(module, None) - - if globals is None: - globals = {} - - return environment.template_class.from_module_dict( - environment, mod.__dict__, globals - ) -- cgit v1.2.3