Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(150)

Side by Side Diff: third_party/jinja2/loaders.py

Issue 23506004: Update Jinja2 (Python template library) to 2.7.1 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebased Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « third_party/jinja2/lexer.py ('k') | third_party/jinja2/meta.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # -*- coding: utf-8 -*- 1 # -*- coding: utf-8 -*-
2 """ 2 """
3 jinja2.loaders 3 jinja2.loaders
4 ~~~~~~~~~~~~~~ 4 ~~~~~~~~~~~~~~
5 5
6 Jinja loader classes. 6 Jinja loader classes.
7 7
8 :copyright: (c) 2010 by the Jinja Team. 8 :copyright: (c) 2010 by the Jinja Team.
9 :license: BSD, see LICENSE for more details. 9 :license: BSD, see LICENSE for more details.
10 """ 10 """
11 import os 11 import os
12 import sys 12 import sys
13 import weakref 13 import weakref
14 from types import ModuleType 14 from types import ModuleType
15 from os import path 15 from os import path
16 try: 16 from hashlib import sha1
17 from hashlib import sha1
18 except ImportError:
19 from sha import new as sha1
20 from jinja2.exceptions import TemplateNotFound 17 from jinja2.exceptions import TemplateNotFound
21 from jinja2.utils import LRUCache, open_if_exists, internalcode 18 from jinja2.utils import open_if_exists, internalcode
19 from jinja2._compat import string_types, iteritems
22 20
23 21
24 def split_template_path(template): 22 def split_template_path(template):
25 """Split a path into segments and perform a sanity check. If it detects 23 """Split a path into segments and perform a sanity check. If it detects
26 '..' in the path it will raise a `TemplateNotFound` error. 24 '..' in the path it will raise a `TemplateNotFound` error.
27 """ 25 """
28 pieces = [] 26 pieces = []
29 for piece in template.split('/'): 27 for piece in template.split('/'):
30 if path.sep in piece \ 28 if path.sep in piece \
31 or (path.altsep and path.altsep in piece) or \ 29 or (path.altsep and path.altsep in piece) or \
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
146 given order: 144 given order:
147 145
148 >>> loader = FileSystemLoader('/path/to/templates') 146 >>> loader = FileSystemLoader('/path/to/templates')
149 >>> loader = FileSystemLoader(['/path/to/templates', '/other/path']) 147 >>> loader = FileSystemLoader(['/path/to/templates', '/other/path'])
150 148
151 Per default the template encoding is ``'utf-8'`` which can be changed 149 Per default the template encoding is ``'utf-8'`` which can be changed
152 by setting the `encoding` parameter to something else. 150 by setting the `encoding` parameter to something else.
153 """ 151 """
154 152
155 def __init__(self, searchpath, encoding='utf-8'): 153 def __init__(self, searchpath, encoding='utf-8'):
156 if isinstance(searchpath, basestring): 154 if isinstance(searchpath, string_types):
157 searchpath = [searchpath] 155 searchpath = [searchpath]
158 self.searchpath = list(searchpath) 156 self.searchpath = list(searchpath)
159 self.encoding = encoding 157 self.encoding = encoding
160 158
161 def get_source(self, environment, template): 159 def get_source(self, environment, template):
162 pieces = split_template_path(template) 160 pieces = split_template_path(template)
163 for searchpath in self.searchpath: 161 for searchpath in self.searchpath:
164 filename = path.join(searchpath, *pieces) 162 filename = path.join(searchpath, *pieces)
165 f = open_if_exists(filename) 163 f = open_if_exists(filename)
166 if f is None: 164 if f is None:
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
267 265
268 Because auto reloading is rarely useful this is disabled per default. 266 Because auto reloading is rarely useful this is disabled per default.
269 """ 267 """
270 268
271 def __init__(self, mapping): 269 def __init__(self, mapping):
272 self.mapping = mapping 270 self.mapping = mapping
273 271
274 def get_source(self, environment, template): 272 def get_source(self, environment, template):
275 if template in self.mapping: 273 if template in self.mapping:
276 source = self.mapping[template] 274 source = self.mapping[template]
277 return source, None, lambda: source != self.mapping.get(template) 275 return source, None, lambda: source == self.mapping.get(template)
278 raise TemplateNotFound(template) 276 raise TemplateNotFound(template)
279 277
280 def list_templates(self): 278 def list_templates(self):
281 return sorted(self.mapping) 279 return sorted(self.mapping)
282 280
283 281
284 class FunctionLoader(BaseLoader): 282 class FunctionLoader(BaseLoader):
285 """A loader that is passed a function which does the loading. The 283 """A loader that is passed a function which does the loading. The
286 function becomes the name of the template passed and has to return either 284 function becomes the name of the template passed and has to return either
287 an unicode string with the template source, a tuple in the form ``(source, 285 an unicode string with the template source, a tuple in the form ``(source,
(...skipping 11 matching lines...) Expand all
299 return value. 297 return value.
300 """ 298 """
301 299
302 def __init__(self, load_func): 300 def __init__(self, load_func):
303 self.load_func = load_func 301 self.load_func = load_func
304 302
305 def get_source(self, environment, template): 303 def get_source(self, environment, template):
306 rv = self.load_func(template) 304 rv = self.load_func(template)
307 if rv is None: 305 if rv is None:
308 raise TemplateNotFound(template) 306 raise TemplateNotFound(template)
309 elif isinstance(rv, basestring): 307 elif isinstance(rv, string_types):
310 return rv, None, None 308 return rv, None, None
311 return rv 309 return rv
312 310
313 311
314 class PrefixLoader(BaseLoader): 312 class PrefixLoader(BaseLoader):
315 """A loader that is passed a dict of loaders where each loader is bound 313 """A loader that is passed a dict of loaders where each loader is bound
316 to a prefix. The prefix is delimited from the template by a slash per 314 to a prefix. The prefix is delimited from the template by a slash per
317 default, which can be changed by setting the `delimiter` argument to 315 default, which can be changed by setting the `delimiter` argument to
318 something else:: 316 something else::
319 317
320 loader = PrefixLoader({ 318 loader = PrefixLoader({
321 'app1': PackageLoader('mypackage.app1'), 319 'app1': PackageLoader('mypackage.app1'),
322 'app2': PackageLoader('mypackage.app2') 320 'app2': PackageLoader('mypackage.app2')
323 }) 321 })
324 322
325 By loading ``'app1/index.html'`` the file from the app1 package is loaded, 323 By loading ``'app1/index.html'`` the file from the app1 package is loaded,
326 by loading ``'app2/index.html'`` the file from the second. 324 by loading ``'app2/index.html'`` the file from the second.
327 """ 325 """
328 326
329 def __init__(self, mapping, delimiter='/'): 327 def __init__(self, mapping, delimiter='/'):
330 self.mapping = mapping 328 self.mapping = mapping
331 self.delimiter = delimiter 329 self.delimiter = delimiter
332 330
333 def get_source(self, environment, template): 331 def get_loader(self, template):
334 try: 332 try:
335 prefix, name = template.split(self.delimiter, 1) 333 prefix, name = template.split(self.delimiter, 1)
336 loader = self.mapping[prefix] 334 loader = self.mapping[prefix]
337 except (ValueError, KeyError): 335 except (ValueError, KeyError):
338 raise TemplateNotFound(template) 336 raise TemplateNotFound(template)
337 return loader, name
338
339 def get_source(self, environment, template):
340 loader, name = self.get_loader(template)
339 try: 341 try:
340 return loader.get_source(environment, name) 342 return loader.get_source(environment, name)
341 except TemplateNotFound: 343 except TemplateNotFound:
342 # re-raise the exception with the correct fileame here. 344 # re-raise the exception with the correct fileame here.
343 # (the one that includes the prefix) 345 # (the one that includes the prefix)
344 raise TemplateNotFound(template) 346 raise TemplateNotFound(template)
345 347
348 @internalcode
349 def load(self, environment, name, globals=None):
350 loader, local_name = self.get_loader(name)
351 try:
352 return loader.load(environment, local_name)
353 except TemplateNotFound:
354 # re-raise the exception with the correct fileame here.
355 # (the one that includes the prefix)
356 raise TemplateNotFound(name)
357
346 def list_templates(self): 358 def list_templates(self):
347 result = [] 359 result = []
348 for prefix, loader in self.mapping.iteritems(): 360 for prefix, loader in iteritems(self.mapping):
349 for template in loader.list_templates(): 361 for template in loader.list_templates():
350 result.append(prefix + self.delimiter + template) 362 result.append(prefix + self.delimiter + template)
351 return result 363 return result
352 364
353 365
354 class ChoiceLoader(BaseLoader): 366 class ChoiceLoader(BaseLoader):
355 """This loader works like the `PrefixLoader` just that no prefix is 367 """This loader works like the `PrefixLoader` just that no prefix is
356 specified. If a template could not be found by one loader the next one 368 specified. If a template could not be found by one loader the next one
357 is tried. 369 is tried.
358 370
(...skipping 10 matching lines...) Expand all
369 self.loaders = loaders 381 self.loaders = loaders
370 382
371 def get_source(self, environment, template): 383 def get_source(self, environment, template):
372 for loader in self.loaders: 384 for loader in self.loaders:
373 try: 385 try:
374 return loader.get_source(environment, template) 386 return loader.get_source(environment, template)
375 except TemplateNotFound: 387 except TemplateNotFound:
376 pass 388 pass
377 raise TemplateNotFound(template) 389 raise TemplateNotFound(template)
378 390
391 @internalcode
392 def load(self, environment, name, globals=None):
393 for loader in self.loaders:
394 try:
395 return loader.load(environment, name, globals)
396 except TemplateNotFound:
397 pass
398 raise TemplateNotFound(name)
399
379 def list_templates(self): 400 def list_templates(self):
380 found = set() 401 found = set()
381 for loader in self.loaders: 402 for loader in self.loaders:
382 found.update(loader.list_templates()) 403 found.update(loader.list_templates())
383 return sorted(found) 404 return sorted(found)
384 405
385 406
386 class _TemplateModule(ModuleType): 407 class _TemplateModule(ModuleType):
387 """Like a normal module but with support for weak references""" 408 """Like a normal module but with support for weak references"""
388 409
(...skipping 12 matching lines...) Expand all
401 """ 422 """
402 423
403 has_source_access = False 424 has_source_access = False
404 425
405 def __init__(self, path): 426 def __init__(self, path):
406 package_name = '_jinja2_module_templates_%x' % id(self) 427 package_name = '_jinja2_module_templates_%x' % id(self)
407 428
408 # create a fake module that looks for the templates in the 429 # create a fake module that looks for the templates in the
409 # path given. 430 # path given.
410 mod = _TemplateModule(package_name) 431 mod = _TemplateModule(package_name)
411 if isinstance(path, basestring): 432 if isinstance(path, string_types):
412 path = [path] 433 path = [path]
413 else: 434 else:
414 path = list(path) 435 path = list(path)
415 mod.__path__ = path 436 mod.__path__ = path
416 437
417 sys.modules[package_name] = weakref.proxy(mod, 438 sys.modules[package_name] = weakref.proxy(mod,
418 lambda x: sys.modules.pop(package_name, None)) 439 lambda x: sys.modules.pop(package_name, None))
419 440
420 # the only strong reference, the sys.modules entry is weak 441 # the only strong reference, the sys.modules entry is weak
421 # so that the garbage collector can remove it once the 442 # so that the garbage collector can remove it once the
(...skipping 19 matching lines...) Expand all
441 mod = __import__(module, None, None, ['root']) 462 mod = __import__(module, None, None, ['root'])
442 except ImportError: 463 except ImportError:
443 raise TemplateNotFound(name) 464 raise TemplateNotFound(name)
444 465
445 # remove the entry from sys.modules, we only want the attribute 466 # remove the entry from sys.modules, we only want the attribute
446 # on the module object we have stored on the loader. 467 # on the module object we have stored on the loader.
447 sys.modules.pop(module, None) 468 sys.modules.pop(module, None)
448 469
449 return environment.template_class.from_module_dict( 470 return environment.template_class.from_module_dict(
450 environment, mod.__dict__, globals) 471 environment, mod.__dict__, globals)
OLDNEW
« no previous file with comments | « third_party/jinja2/lexer.py ('k') | third_party/jinja2/meta.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698