NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

loaders.py (9235B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\lib\jinja2\loaders.py
      2 import os
      3 import sys
      4 import weakref
      5 from types import ModuleType
      6 from os import path
      7 try:
      8     from hashlib import sha1
      9 except ImportError:
     10     from sha import new as sha1
     11 
     12 from jinja2.exceptions import TemplateNotFound
     13 from jinja2.utils import LRUCache, open_if_exists, internalcode
     14 
     15 def split_template_path(template):
     16     pieces = []
     17     for piece in template.split('/'):
     18         if path.sep in piece or path.altsep and path.altsep in piece or piece == path.pardir:
     19             raise TemplateNotFound(template)
     20         elif piece and piece != '.':
     21             pieces.append(piece)
     22 
     23     return pieces
     24 
     25 
     26 class BaseLoader(object):
     27     has_source_access = True
     28 
     29     def get_source(self, environment, template):
     30         if not self.has_source_access:
     31             raise RuntimeError('%s cannot provide access to the source' % self.__class__.__name__)
     32         raise TemplateNotFound(template)
     33 
     34     def list_templates(self):
     35         raise TypeError('this loader cannot iterate over all templates')
     36 
     37     @internalcode
     38     def load(self, environment, name, globals = None):
     39         code = None
     40         if globals is None:
     41             globals = {}
     42         source, filename, uptodate = self.get_source(environment, name)
     43         bcc = environment.bytecode_cache
     44         if bcc is not None:
     45             bucket = bcc.get_bucket(environment, name, filename, source)
     46             code = bucket.code
     47         if code is None:
     48             code = environment.compile(source, name, filename)
     49         if bcc is not None and bucket.code is None:
     50             bucket.code = code
     51             bcc.set_bucket(bucket)
     52         return environment.template_class.from_code(environment, code, globals, uptodate)
     53 
     54 
     55 class FileSystemLoader(BaseLoader):
     56 
     57     def __init__(self, searchpath, encoding = 'utf-8'):
     58         if isinstance(searchpath, basestring):
     59             searchpath = [searchpath]
     60         self.searchpath = list(searchpath)
     61         self.encoding = encoding
     62 
     63     def get_source(self, environment, template):
     64         pieces = split_template_path(template)
     65         for searchpath in self.searchpath:
     66             filename = path.join(searchpath, *pieces)
     67             f = open_if_exists(filename)
     68             if f is None:
     69                 continue
     70             try:
     71                 contents = f.read().decode(self.encoding)
     72             finally:
     73                 f.close()
     74 
     75             mtime = path.getmtime(filename)
     76 
     77             def uptodate():
     78                 try:
     79                     return path.getmtime(filename) == mtime
     80                 except OSError:
     81                     return False
     82 
     83             return (contents, filename, uptodate)
     84 
     85         raise TemplateNotFound(template)
     86 
     87     def list_templates(self):
     88         found = set()
     89         for searchpath in self.searchpath:
     90             for dirpath, dirnames, filenames in os.walk(searchpath):
     91                 for filename in filenames:
     92                     template = os.path.join(dirpath, filename)[len(searchpath):].strip(os.path.sep).replace(os.path.sep, '/')
     93                     if template[:2] == './':
     94                         template = template[2:]
     95                     if template not in found:
     96                         found.add(template)
     97 
     98         return sorted(found)
     99 
    100 
    101 class PackageLoader(BaseLoader):
    102 
    103     def __init__(self, package_name, package_path = 'templates', encoding = 'utf-8'):
    104         from pkg_resources import DefaultProvider, ResourceManager, get_provider
    105         provider = get_provider(package_name)
    106         self.encoding = encoding
    107         self.manager = ResourceManager()
    108         self.filesystem_bound = isinstance(provider, DefaultProvider)
    109         self.provider = provider
    110         self.package_path = package_path
    111 
    112     def get_source(self, environment, template):
    113         pieces = split_template_path(template)
    114         p = '/'.join((self.package_path,) + tuple(pieces))
    115         if not self.provider.has_resource(p):
    116             raise TemplateNotFound(template)
    117         filename = uptodate = None
    118         if self.filesystem_bound:
    119             filename = self.provider.get_resource_filename(self.manager, p)
    120             mtime = path.getmtime(filename)
    121 
    122             def uptodate():
    123                 try:
    124                     return path.getmtime(filename) == mtime
    125                 except OSError:
    126                     return False
    127 
    128         source = self.provider.get_resource_string(self.manager, p)
    129         return (source.decode(self.encoding), filename, uptodate)
    130 
    131     def list_templates(self):
    132         path = self.package_path
    133         if path[:2] == './':
    134             path = path[2:]
    135         elif path == '.':
    136             path = ''
    137         offset = len(path)
    138         results = []
    139 
    140         def _walk(path):
    141             for filename in self.provider.resource_listdir(path):
    142                 fullname = path + '/' + filename
    143                 if self.provider.resource_isdir(fullname):
    144                     _walk(fullname)
    145                 else:
    146                     results.append(fullname[offset:].lstrip('/'))
    147 
    148         _walk(path)
    149         results.sort()
    150         return results
    151 
    152 
    153 class DictLoader(BaseLoader):
    154 
    155     def __init__(self, mapping):
    156         self.mapping = mapping
    157 
    158     def get_source(self, environment, template):
    159         if template in self.mapping:
    160             source = self.mapping[template]
    161             return (source, None, lambda : source != self.mapping.get(template))
    162         raise TemplateNotFound(template)
    163 
    164     def list_templates(self):
    165         return sorted(self.mapping)
    166 
    167 
    168 class FunctionLoader(BaseLoader):
    169 
    170     def __init__(self, load_func):
    171         self.load_func = load_func
    172 
    173     def get_source(self, environment, template):
    174         rv = self.load_func(template)
    175         if rv is None:
    176             raise TemplateNotFound(template)
    177         elif isinstance(rv, basestring):
    178             return (rv, None, None)
    179         return rv
    180 
    181 
    182 class PrefixLoader(BaseLoader):
    183 
    184     def __init__(self, mapping, delimiter = '/'):
    185         self.mapping = mapping
    186         self.delimiter = delimiter
    187 
    188     def get_loader(self, template):
    189         try:
    190             prefix, name = template.split(self.delimiter, 1)
    191             loader = self.mapping[prefix]
    192         except (ValueError, KeyError):
    193             raise TemplateNotFound(template)
    194 
    195         return (loader, name)
    196 
    197     def get_source(self, environment, template):
    198         loader, name = self.get_loader(template)
    199         try:
    200             return loader.get_source(environment, name)
    201         except TemplateNotFound:
    202             raise TemplateNotFound(template)
    203 
    204     @internalcode
    205     def load(self, environment, name, globals = None):
    206         loader, local_name = self.get_loader(name)
    207         try:
    208             return loader.load(environment, local_name)
    209         except TemplateNotFound:
    210             raise TemplateNotFound(name)
    211 
    212     def list_templates(self):
    213         result = []
    214         for prefix, loader in self.mapping.iteritems():
    215             for template in loader.list_templates():
    216                 result.append(prefix + self.delimiter + template)
    217 
    218         return result
    219 
    220 
    221 class ChoiceLoader(BaseLoader):
    222 
    223     def __init__(self, loaders):
    224         self.loaders = loaders
    225 
    226     def get_source(self, environment, template):
    227         for loader in self.loaders:
    228             try:
    229                 return loader.get_source(environment, template)
    230             except TemplateNotFound:
    231                 pass
    232 
    233         raise TemplateNotFound(template)
    234 
    235     @internalcode
    236     def load(self, environment, name, globals = None):
    237         for loader in self.loaders:
    238             try:
    239                 return loader.load(environment, name, globals)
    240             except TemplateNotFound:
    241                 pass
    242 
    243         raise TemplateNotFound(name)
    244 
    245     def list_templates(self):
    246         found = set()
    247         for loader in self.loaders:
    248             found.update(loader.list_templates())
    249 
    250         return sorted(found)
    251 
    252 
    253 class _TemplateModule(ModuleType):
    254     pass
    255 
    256 
    257 class ModuleLoader(BaseLoader):
    258     has_source_access = False
    259 
    260     def __init__(self, path):
    261         package_name = '_jinja2_module_templates_%x' % id(self)
    262         mod = _TemplateModule(package_name)
    263         if isinstance(path, basestring):
    264             path = [path]
    265         else:
    266             path = list(path)
    267         mod.__path__ = path
    268         sys.modules[package_name] = weakref.proxy(mod, lambda x: sys.modules.pop(package_name, None))
    269         self.module = mod
    270         self.package_name = package_name
    271 
    272     @staticmethod
    273     def get_template_key(name):
    274         return 'tmpl_' + sha1(name.encode('utf-8')).hexdigest()
    275 
    276     @staticmethod
    277     def get_module_filename(name):
    278         return ModuleLoader.get_template_key(name) + '.py'
    279 
    280     @internalcode
    281     def load(self, environment, name, globals = None):
    282         key = self.get_template_key(name)
    283         module = '%s.%s' % (self.package_name, key)
    284         mod = getattr(self.module, module, None)
    285         if mod is None:
    286             try:
    287                 mod = __import__(module, None, None, ['root'])
    288             except ImportError:
    289                 raise TemplateNotFound(name)
    290 
    291             sys.modules.pop(module, None)
    292         return environment.template_class.from_module_dict(environment, mod.__dict__, globals)