import sys
PY2 = sys.version_info[0] == 2
+_identity = lambda x: x
if not PY2:
+
unichr = chr
range_type = range
text_type = str
izip = zip
intern = sys.intern
- implements_iterator = lambda x: x
- implements_to_string = lambda x: x
+ implements_iterator = _identity
+ implements_to_string = _identity
+ encode_filename = _identity
get_next = lambda x: x.__next__
else:
unichr = unichr
get_next = lambda x: x.next
+ def encode_filename(filename):
+ if isinstance(filename, unicode):
+ return filename.encode('utf-8')
+ return filename
try:
next = next
_tb = sys.exc_info()[2]
traceback_type = type(_tb)
frame_type = type(_tb.tb_frame)
+
+
+try:
+ from urllib.parse import quote_from_bytes as url_quote
+except ImportError:
+ from urllib import quote as url_quote
+
+
+try:
+ from thread import allocate_lock
+except ImportError:
+ try:
+ from threading import Lock as allocate_lock
+ except ImportError:
+ from dummy_thread import allocate_lock
from jinja2.exceptions import TemplateSyntaxError, TemplateNotFound, \
TemplatesNotFound, TemplateRuntimeError
from jinja2.utils import import_string, LRUCache, Markup, missing, \
- concat, consume, internalcode, _encode_filename
+ concat, consume, internalcode
from jinja2._compat import imap, ifilter, string_types, iteritems, \
text_type, reraise, implements_iterator, implements_to_string, \
- get_next
+ get_next, encode_filename
from functools import reduce
def _parse(self, source, name, filename):
"""Internal parsing function used by `parse` and `compile`."""
- return Parser(self, source, name, _encode_filename(filename)).parse()
+ return Parser(self, source, name, encode_filename(filename)).parse()
def lex(self, source, name=None, filename=None):
"""Lex the given sourcecode and return a generator that yields
if filename is None:
filename = '<template>'
else:
- filename = _encode_filename(filename)
+ filename = encode_filename(filename)
return self._compile(source, filename)
except TemplateSyntaxError:
exc_info = sys.exc_info()
filename = ModuleLoader.get_module_filename(name)
if py_compile:
- c = self._compile(code, _encode_filename(filename))
+ c = self._compile(code, encode_filename(filename))
write_file(filename + 'c', py_header +
marshal.dumps(c), 'wb')
log_function('Byte-compiled "%s" as %s' %
:license: BSD, see LICENSE for more details.
"""
import re
-import sys
import errno
-try:
- from urllib.parse import quote_from_bytes as url_quote
-except ImportError:
- from urllib import quote as url_quote
-try:
- from thread import allocate_lock
-except ImportError:
- try:
- from _thread import allocate_lock # py 3
- except ImportError:
- from dummy_thread import allocate_lock
from collections import deque
-from jinja2._compat import text_type, string_types, implements_iterator, PY2
+from jinja2._compat import text_type, string_types, implements_iterator, \
+ allocate_lock, url_quote, encode_filename, PY2
_word_split_re = re.compile(r'(\s+)')
concat = u''.join
-# if this python version is unable to deal with unicode filenames
-# when passed to encode we let this function encode it properly.
-# This is used in a couple of places. As far as Jinja is concerned
-# filenames are unicode *or* bytestrings in 2.x and unicode only in
-# 3.x because compile cannot handle bytes
-if PY2:
- def _encode_filename(filename):
- if isinstance(filename, unicode):
- return filename.encode('utf-8')
- return filename
-else:
- def _encode_filename(filename):
- assert filename is None or isinstance(filename, str), \
- 'filenames must be strings'
- return filename
-
-
def contextfunction(f):
"""This decorator can be used to mark a function or method context callable.
A context callable is passed the active :class:`Context` as first argument when