| Index: mojo/public/third_party/jinja2/loaders.py
|
| diff --git a/mojo/public/third_party/jinja2/loaders.py b/mojo/public/third_party/jinja2/loaders.py
|
| deleted file mode 100644
|
| index a9a2625274c28c36125ecd01f70601194e36d6a1..0000000000000000000000000000000000000000
|
| --- a/mojo/public/third_party/jinja2/loaders.py
|
| +++ /dev/null
|
| @@ -1,471 +0,0 @@
|
| -# -*- coding: utf-8 -*-
|
| -"""
|
| - jinja2.loaders
|
| - ~~~~~~~~~~~~~~
|
| -
|
| - Jinja loader classes.
|
| -
|
| - :copyright: (c) 2010 by the Jinja Team.
|
| - :license: BSD, see LICENSE for more details.
|
| -"""
|
| -import os
|
| -import sys
|
| -import weakref
|
| -from types import ModuleType
|
| -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, iteritems
|
| -
|
| -
|
| -def split_template_path(template):
|
| - """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 path.sep in piece \
|
| - or (path.altsep and path.altsep in piece) or \
|
| - piece == path.pardir:
|
| - raise TemplateNotFound(template)
|
| - elif piece and piece != '.':
|
| - pieces.append(piece)
|
| - return pieces
|
| -
|
| -
|
| -class BaseLoader(object):
|
| - """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 file(path) as f:
|
| - source = f.read().decode('utf-8')
|
| - 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, template):
|
| - """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 unicode string or a ASCII bytestring. 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('%s cannot provide access to the source' %
|
| - self.__class__.__name__)
|
| - raise TemplateNotFound(template)
|
| -
|
| - def list_templates(self):
|
| - """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, name, globals=None):
|
| - """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):
|
| - """Loads templates from the file system. This loader can find templates
|
| - in folders on the file system and is the preferred way to load them.
|
| -
|
| - The loader takes the path to the templates as string, or if multiple
|
| - locations are wanted a list of them which is then looked up in the
|
| - given order:
|
| -
|
| - >>> loader = FileSystemLoader('/path/to/templates')
|
| - >>> loader = FileSystemLoader(['/path/to/templates', '/other/path'])
|
| -
|
| - Per default the template encoding is ``'utf-8'`` which can be changed
|
| - by setting the `encoding` parameter to something else.
|
| - """
|
| -
|
| - def __init__(self, searchpath, encoding='utf-8'):
|
| - if isinstance(searchpath, string_types):
|
| - searchpath = [searchpath]
|
| - self.searchpath = list(searchpath)
|
| - self.encoding = encoding
|
| -
|
| - def get_source(self, environment, template):
|
| - pieces = split_template_path(template)
|
| - for searchpath in self.searchpath:
|
| - filename = path.join(searchpath, *pieces)
|
| - f = open_if_exists(filename)
|
| - if f is None:
|
| - continue
|
| - try:
|
| - contents = f.read().decode(self.encoding)
|
| - finally:
|
| - f.close()
|
| -
|
| - mtime = path.getmtime(filename)
|
| - def uptodate():
|
| - try:
|
| - return path.getmtime(filename) == mtime
|
| - except OSError:
|
| - return False
|
| - return contents, filename, uptodate
|
| - raise TemplateNotFound(template)
|
| -
|
| - def list_templates(self):
|
| - found = set()
|
| - for searchpath in self.searchpath:
|
| - for dirpath, dirnames, filenames in os.walk(searchpath):
|
| - 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 python eggs or packages. It is constructed with
|
| - the name of the python package and the path to the templates in that
|
| - package::
|
| -
|
| - loader = PackageLoader('mypackage', 'views')
|
| -
|
| - If the package path is not given, ``'templates'`` is assumed.
|
| -
|
| - Per default the template encoding is ``'utf-8'`` which can be changed
|
| - by setting the `encoding` parameter to something else. Due to the nature
|
| - of eggs it's only possible to reload templates if the package was loaded
|
| - from the file system and not a zip file.
|
| - """
|
| -
|
| - def __init__(self, package_name, package_path='templates',
|
| - encoding='utf-8'):
|
| - from pkg_resources import DefaultProvider, ResourceManager, \
|
| - get_provider
|
| - provider = get_provider(package_name)
|
| - self.encoding = encoding
|
| - self.manager = ResourceManager()
|
| - self.filesystem_bound = isinstance(provider, DefaultProvider)
|
| - self.provider = provider
|
| - self.package_path = package_path
|
| -
|
| - def get_source(self, environment, template):
|
| - pieces = split_template_path(template)
|
| - p = '/'.join((self.package_path,) + tuple(pieces))
|
| - if not self.provider.has_resource(p):
|
| - raise TemplateNotFound(template)
|
| -
|
| - filename = uptodate = None
|
| - if self.filesystem_bound:
|
| - filename = self.provider.get_resource_filename(self.manager, p)
|
| - mtime = path.getmtime(filename)
|
| - def uptodate():
|
| - try:
|
| - return path.getmtime(filename) == mtime
|
| - except OSError:
|
| - return False
|
| -
|
| - source = self.provider.get_resource_string(self.manager, p)
|
| - return source.decode(self.encoding), filename, uptodate
|
| -
|
| - def list_templates(self):
|
| - path = self.package_path
|
| - if path[:2] == './':
|
| - path = path[2:]
|
| - elif path == '.':
|
| - path = ''
|
| - offset = len(path)
|
| - results = []
|
| - def _walk(path):
|
| - for filename in self.provider.resource_listdir(path):
|
| - fullname = path + '/' + filename
|
| - if self.provider.resource_isdir(fullname):
|
| - _walk(fullname)
|
| - else:
|
| - results.append(fullname[offset:].lstrip('/'))
|
| - _walk(path)
|
| - results.sort()
|
| - return results
|
| -
|
| -
|
| -class DictLoader(BaseLoader):
|
| - """Loads a template from a python dict. It's passed a dict of unicode
|
| - strings bound to template names. 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):
|
| - self.mapping = mapping
|
| -
|
| - def get_source(self, environment, template):
|
| - 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):
|
| - return sorted(self.mapping)
|
| -
|
| -
|
| -class FunctionLoader(BaseLoader):
|
| - """A loader that is passed a function which does the loading. The
|
| - function becomes the name of the template passed and has to return either
|
| - an unicode 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):
|
| - self.load_func = load_func
|
| -
|
| - def get_source(self, environment, template):
|
| - rv = self.load_func(template)
|
| - if rv is None:
|
| - raise TemplateNotFound(template)
|
| - elif isinstance(rv, string_types):
|
| - 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, delimiter='/'):
|
| - self.mapping = mapping
|
| - self.delimiter = delimiter
|
| -
|
| - def get_loader(self, template):
|
| - try:
|
| - prefix, name = template.split(self.delimiter, 1)
|
| - loader = self.mapping[prefix]
|
| - except (ValueError, KeyError):
|
| - raise TemplateNotFound(template)
|
| - return loader, name
|
| -
|
| - def get_source(self, environment, template):
|
| - loader, name = self.get_loader(template)
|
| - try:
|
| - return loader.get_source(environment, name)
|
| - except TemplateNotFound:
|
| - # re-raise the exception with the correct fileame here.
|
| - # (the one that includes the prefix)
|
| - raise TemplateNotFound(template)
|
| -
|
| - @internalcode
|
| - def load(self, environment, name, globals=None):
|
| - loader, local_name = self.get_loader(name)
|
| - try:
|
| - return loader.load(environment, local_name)
|
| - except TemplateNotFound:
|
| - # re-raise the exception with the correct fileame here.
|
| - # (the one that includes the prefix)
|
| - raise TemplateNotFound(name)
|
| -
|
| - def list_templates(self):
|
| - result = []
|
| - for prefix, loader in iteritems(self.mapping):
|
| - 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):
|
| - self.loaders = loaders
|
| -
|
| - def get_source(self, environment, template):
|
| - for loader in self.loaders:
|
| - try:
|
| - return loader.get_source(environment, template)
|
| - except TemplateNotFound:
|
| - pass
|
| - raise TemplateNotFound(template)
|
| -
|
| - @internalcode
|
| - def load(self, environment, name, globals=None):
|
| - for loader in self.loaders:
|
| - try:
|
| - return loader.load(environment, name, globals)
|
| - except TemplateNotFound:
|
| - pass
|
| - raise TemplateNotFound(name)
|
| -
|
| - def list_templates(self):
|
| - 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):
|
| - package_name = '_jinja2_module_templates_%x' % id(self)
|
| -
|
| - # create a fake module that looks for the templates in the
|
| - # path given.
|
| - mod = _TemplateModule(package_name)
|
| - if isinstance(path, string_types):
|
| - path = [path]
|
| - else:
|
| - path = list(path)
|
| - mod.__path__ = 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):
|
| - return 'tmpl_' + sha1(name.encode('utf-8')).hexdigest()
|
| -
|
| - @staticmethod
|
| - def get_module_filename(name):
|
| - return ModuleLoader.get_template_key(name) + '.py'
|
| -
|
| - @internalcode
|
| - def load(self, environment, name, globals=None):
|
| - key = self.get_template_key(name)
|
| - module = '%s.%s' % (self.package_name, key)
|
| - mod = getattr(self.module, module, None)
|
| - if mod is None:
|
| - try:
|
| - mod = __import__(module, None, None, ['root'])
|
| - except ImportError:
|
| - raise TemplateNotFound(name)
|
| -
|
| - # 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)
|
| -
|
| - return environment.template_class.from_module_dict(
|
| - environment, mod.__dict__, globals)
|
|
|