]> git.ipfire.org Git - thirdparty/jinja.git/commitdiff
Moved all six usages (ignoring testsuite) into jinja2._compat
authorArmin Ronacher <armin.ronacher@active-4.com>
Sun, 19 May 2013 13:16:13 +0000 (14:16 +0100)
committerArmin Ronacher <armin.ronacher@active-4.com>
Sun, 19 May 2013 13:16:13 +0000 (14:16 +0100)
16 files changed:
jinja2/_compat.py
jinja2/bccache.py
jinja2/compiler.py
jinja2/debug.py
jinja2/environment.py
jinja2/exceptions.py
jinja2/ext.py
jinja2/filters.py
jinja2/lexer.py
jinja2/loaders.py
jinja2/meta.py
jinja2/nodes.py
jinja2/runtime.py
jinja2/sandbox.py
jinja2/tests.py
jinja2/utils.py

index 8c1963c497cf46913b77482fefbf3cdcdf0a015e..f10ef651ce863dcf71e93825e07ed5ada0a40c59 100644 (file)
@@ -12,6 +12,9 @@
     :license: BSD, see LICENSE for details.
 """
 import six
+import sys
+
+PY3 = six.PY3
 
 # https://bitbucket.org/gutworth/six/issue/25/add-unichr
 try:
@@ -22,3 +25,52 @@ except NameError:
 range_type = six.moves.xrange
 next = six.advance_iterator
 imap = six.moves.map
+izip = six.moves.zip
+text_type = six.text_type
+string_types = six.string_types
+
+iteritems = six.iteritems
+
+if six.PY3:
+    from io import BytesIO, StringIO
+    NativeStringIO = StringIO
+else:
+    from cStringIO import StringIO as BytesIO
+    from StringIO import StringIO
+    NativeStringIO = BytesIO
+
+try:
+    import cPickle as pickle
+except ImportError:
+    import pickle
+
+ifilter = six.moves.filter
+reraise = six.reraise
+Iterator = six.Iterator
+with_metaclass = six.with_metaclass
+
+try:
+    from collections import Mapping as mapping_types
+except ImportError:
+    import UserDict
+    mapping_types = (UserDict.UserDict, UserDict.DictMixin, dict)
+
+
+# common types.  These do exist in the special types module too which however
+# does not exist in IronPython out of the box.  Also that way we don't have
+# to deal with implementation specific stuff here
+class _C(object):
+    def method(self): pass
+def _func():
+    yield None
+function_type = type(_func)
+generator_type = type(_func())
+method_type = type(_C().method)
+code_type = type(_C.method.__code__)
+try:
+    raise TypeError()
+except TypeError:
+    _tb = sys.exc_info()[2]
+    traceback_type = type(_tb)
+    frame_type = type(_tb.tb_frame)
+del _C, _tb, _func
index f02291801e91c2263121b855b6d033a916c2e397..dbfc3c2dce3f46a09b6ab3dcd11716de7c445e8f 100644 (file)
@@ -18,14 +18,10 @@ from os import path, listdir
 import sys
 import marshal
 import tempfile
-from six.moves import cPickle as pickle
-from six import BytesIO
 import fnmatch
-try:
-    from hashlib import sha1
-except ImportError:
-    from sha import new as sha1
+from hashlib import sha1
 from jinja2.utils import open_if_exists
+from jinja2._compat import BytesIO, pickle
 
 
 # marshal works better on 3.x, one hack less required
index ce8e06d21cbda4f76b253fb6021516b7d26e79ca..4c7a52df5d2e7ace7aa545a4ea8bf8026a6b1346 100644 (file)
@@ -8,8 +8,6 @@
     :copyright: (c) 2010 by the Jinja Team.
     :license: BSD, see LICENSE for more details.
 """
-import six
-
 from itertools import chain
 from copy import deepcopy
 from jinja2 import nodes
@@ -17,8 +15,8 @@ from jinja2.nodes import EvalContext
 from jinja2.visitor import NodeVisitor
 from jinja2.exceptions import TemplateAssertionError
 from jinja2.utils import Markup, concat, escape, is_python_keyword
-from jinja2._compat import range_type, next
-from six.moves import cStringIO as StringIO, map
+from jinja2._compat import range_type, next, text_type, string_types, \
+     iteritems, NativeStringIO, imap
 
 
 operators = {
@@ -69,7 +67,7 @@ def has_safe_repr(value):
     if value is None or value is NotImplemented or value is Ellipsis:
         return True
     if isinstance(value, (bool, int, float, complex, range_type,
-            Markup) + six.string_types):
+            Markup) + string_types):
         return True
     if isinstance(value, (tuple, list, set, frozenset)):
         for item in value:
@@ -77,7 +75,7 @@ def has_safe_repr(value):
                 return False
         return True
     elif isinstance(value, dict):
-        for key, value in six.iteritems(value):
+        for key, value in iteritems(value):
             if not has_safe_repr(key):
                 return False
             if not has_safe_repr(value):
@@ -367,7 +365,7 @@ class CodeGenerator(NodeVisitor):
     def __init__(self, environment, name, filename, stream=None,
                  defer_init=False):
         if stream is None:
-            stream = StringIO()
+            stream = NativeStringIO()
         self.environment = environment
         self.name = name
         self.filename = filename
@@ -541,7 +539,7 @@ class CodeGenerator(NodeVisitor):
                 self.write(', ')
                 self.visit(kwarg, frame)
             if extra_kwargs is not None:
-                for key, value in six.iteritems(extra_kwargs):
+                for key, value in iteritems(extra_kwargs):
                     self.write(', %s=%s' % (key, value))
         if node.dyn_args:
             self.write(', *')
@@ -557,7 +555,7 @@ class CodeGenerator(NodeVisitor):
                 self.visit(kwarg.value, frame)
                 self.write(', ')
             if extra_kwargs is not None:
-                for key, value in six.iteritems(extra_kwargs):
+                for key, value in iteritems(extra_kwargs):
                     self.write('%r: %s, ' % (key, value))
             if node.dyn_kwargs is not None:
                 self.write('}, **')
@@ -624,7 +622,7 @@ class CodeGenerator(NodeVisitor):
 
     def pop_scope(self, aliases, frame):
         """Restore all aliases and delete unused variables."""
-        for name, alias in six.iteritems(aliases):
+        for name, alias in iteritems(aliases):
             self.writeline('l_%s = %s' % (name, alias))
         to_delete = set()
         for name in frame.identifiers.declared_locally:
@@ -826,7 +824,7 @@ class CodeGenerator(NodeVisitor):
             self.outdent(2 + (not self.has_known_extends))
 
         # at this point we now have the blocks collected and can visit them too.
-        for name, block in six.iteritems(self.blocks):
+        for name, block in iteritems(self.blocks):
             block_frame = Frame(eval_ctx)
             block_frame.inspect(block.body)
             block_frame.block = name
@@ -930,7 +928,7 @@ class CodeGenerator(NodeVisitor):
 
         func_name = 'get_or_select_template'
         if isinstance(node.template, nodes.Const):
-            if isinstance(node.template.value, six.string_types):
+            if isinstance(node.template.value, string_types):
                 func_name = 'get_template'
             elif isinstance(node.template.value, (tuple, list)):
                 func_name = 'select_template'
@@ -1039,7 +1037,7 @@ class CodeGenerator(NodeVisitor):
                                discarded_names[0])
             else:
                 self.writeline('context.exported_vars.difference_'
-                               'update((%s))' % ', '.join(map(repr, discarded_names)))
+                               'update((%s))' % ', '.join(imap(repr, discarded_names)))
 
     def visit_For(self, node, frame):
         # when calculating the nodes for the inner frame we have to exclude
@@ -1224,9 +1222,9 @@ class CodeGenerator(NodeVisitor):
             return
 
         if self.environment.finalize:
-            finalize = lambda x: six.text_type(self.environment.finalize(x))
+            finalize = lambda x: text_type(self.environment.finalize(x))
         else:
-            finalize = six.text_type
+            finalize = text_type
 
         # if we are inside a frame that requires output checking, we do so
         outdent_later = False
@@ -1375,7 +1373,7 @@ class CodeGenerator(NodeVisitor):
                                    public_names[0])
                 else:
                     self.writeline('context.exported_vars.update((%s))' %
-                                   ', '.join(map(repr, public_names)))
+                                   ', '.join(imap(repr, public_names)))
 
     # -- Expression Visitors
 
index 31c25ccc0f957260090d66c196cf4437ff4e63a4..815cc18a4f8fd76e747835f24c1297a7d2264628 100644 (file)
@@ -13,9 +13,9 @@
 import sys
 import traceback
 from types import TracebackType
-from jinja2.utils import CodeType, missing, internal_code
+from jinja2.utils import missing, internal_code
 from jinja2.exceptions import TemplateSyntaxError
-import six
+from jinja2._compat import iteritems, reraise, code_type
 
 # on pypy we can take advantage of transparent proxies
 try:
@@ -190,7 +190,7 @@ def translate_exception(exc_info, initial_skip=0):
     # reraise it unchanged.
     # XXX: can we backup here?  when could this happen?
     if not frames:
-        six.reraise(exc_info[0], exc_info[1], exc_info[2])
+        reraise(exc_info[0], exc_info[1], exc_info[2])
 
     return ProcessedTraceback(exc_info[0], exc_info[1], frames)
 
@@ -207,7 +207,7 @@ def fake_exc_info(exc_info, filename, lineno):
             locals = ctx.get_all()
         else:
             locals = {}
-        for name, value in six.iteritems(real_locals):
+        for name, value in iteritems(real_locals):
             if name.startswith('l_') and value is not missing:
                 locals[name[2:]] = value
 
@@ -245,11 +245,11 @@ def fake_exc_info(exc_info, filename, lineno):
                 location = 'block "%s"' % function[6:]
             else:
                 location = 'template'
-        code = CodeType(0, code.co_nlocals, code.co_stacksize,
-                        code.co_flags, code.co_code, code.co_consts,
-                        code.co_names, code.co_varnames, filename,
-                        location, code.co_firstlineno,
-                        code.co_lnotab, (), ())
+        code = code_type(0, code.co_nlocals, code.co_stacksize,
+                         code.co_flags, code.co_code, code.co_consts,
+                         code.co_names, code.co_varnames, filename,
+                         location, code.co_firstlineno,
+                         code.co_lnotab, (), ())
     except:
         pass
 
index 450cac147ab33ab6e2c31c8c9aeb6ac3389ed7e9..ee35b89704ab4c7d5a1edfcb6499120581695425 100644 (file)
@@ -27,9 +27,9 @@ from jinja2.exceptions import TemplateSyntaxError, TemplateNotFound, \
      TemplatesNotFound, TemplateRuntimeError
 from jinja2.utils import import_string, LRUCache, Markup, missing, \
      concat, consume, internalcode, _encode_filename
-import six
+from jinja2._compat import imap, ifilter, string_types, iteritems, \
+     text_type, reraise, PY3, Iterator, next
 from functools import reduce
-from six.moves import filter, map
 
 
 # for direct template usage we have up to ten living environments
@@ -80,7 +80,7 @@ def load_extensions(environment, extensions):
     """
     result = {}
     for extension in extensions:
-        if isinstance(extension, six.string_types):
+        if isinstance(extension, string_types):
             extension = import_string(extension)
         result[extension.identifier] = extension(environment)
     return result
@@ -315,7 +315,7 @@ class Environment(object):
         yet.  This is used by :ref:`extensions <writing-extensions>` to register
         callbacks and configuration values without breaking inheritance.
         """
-        for key, value in six.iteritems(attributes):
+        for key, value in iteritems(attributes):
             if not hasattr(self, key):
                 setattr(self, key, value)
 
@@ -347,7 +347,7 @@ class Environment(object):
         rv.overlayed = True
         rv.linked_to = self
 
-        for key, value in six.iteritems(args):
+        for key, value in iteritems(args):
             if value is not missing:
                 setattr(rv, key, value)
 
@@ -357,7 +357,7 @@ class Environment(object):
             rv.cache = copy_cache(self.cache)
 
         rv.extensions = {}
-        for key, value in six.iteritems(self.extensions):
+        for key, value in iteritems(self.extensions):
             rv.extensions[key] = value.bind(rv)
         if extensions is not missing:
             rv.extensions.update(load_extensions(rv, extensions))
@@ -376,7 +376,7 @@ class Environment(object):
         try:
             return obj[argument]
         except (TypeError, LookupError):
-            if isinstance(argument, six.string_types):
+            if isinstance(argument, string_types):
                 try:
                     attr = str(argument)
                 except Exception:
@@ -467,7 +467,7 @@ class Environment(object):
         of the extensions to be applied you have to filter source through
         the :meth:`preprocess` method.
         """
-        source = six.text_type(source)
+        source = text_type(source)
         try:
             return self.lexer.tokeniter(source, name, filename)
         except TemplateSyntaxError:
@@ -480,7 +480,7 @@ class Environment(object):
         because there you usually only want the actual source tokenized.
         """
         return reduce(lambda s, e: e.preprocess(s, name, filename),
-                      self.iter_extensions(), six.text_type(source))
+                      self.iter_extensions(), text_type(source))
 
     def _tokenize(self, source, name, filename=None, state=None):
         """Called by the parser to do the preprocessing and filtering
@@ -534,7 +534,7 @@ class Environment(object):
         """
         source_hint = None
         try:
-            if isinstance(source, six.string_types):
+            if isinstance(source, string_types):
                 source_hint = source
                 source = self._parse(source, name, filename)
             if self.optimized:
@@ -708,7 +708,7 @@ class Environment(object):
             filter_func = lambda x: '.' in x and \
                                     x.rsplit('.', 1)[1] in extensions
         if filter_func is not None:
-            x = filter(filter_func, x)
+            x = ifilter(filter_func, x)
         return x
 
     def handle_exception(self, exc_info=None, rendered=False, source_hint=None):
@@ -731,7 +731,7 @@ class Environment(object):
         if self.exception_handler is not None:
             self.exception_handler(traceback)
         exc_type, exc_value, tb = traceback.standard_exc_info
-        six.reraise(exc_type, exc_value, tb)
+        reraise(exc_type, exc_value, tb)
 
     def join_path(self, template, parent):
         """Join a template with the parent.  By default all the lookups are
@@ -818,7 +818,7 @@ class Environment(object):
 
         .. versionadded:: 2.3
         """
-        if isinstance(template_name_or_list, six.string_types):
+        if isinstance(template_name_or_list, string_types):
             return self.get_template(template_name_or_list, parent, globals)
         elif isinstance(template_name_or_list, Template):
             return template_name_or_list
@@ -1040,7 +1040,7 @@ class Template(object):
     @property
     def debug_info(self):
         """The debug info mapping."""
-        return [tuple(map(int, x.split('='))) for x in
+        return [tuple(imap(int, x.split('='))) for x in
                 self._debug_info.split('&')]
 
     def __repr__(self):
@@ -1067,7 +1067,7 @@ class TemplateModule(object):
 
     def __str__(self):
         s = self.__unicode__()
-        return s if six.PY3 else s.encode('utf-8')
+        return s if PY3 else s.encode('utf-8')
 
     def __unicode__(self):
         return concat(self._body_stream)
@@ -1099,7 +1099,7 @@ class TemplateExpression(object):
         return rv
 
 
-class TemplateStream(six.Iterator):
+class TemplateStream(Iterator):
     """A template stream works pretty much like an ordinary python generator
     but it can buffer multiple items to reduce the number of total iterations.
     Per default the output is unbuffered which means that for every unbuffered
@@ -1124,7 +1124,7 @@ class TemplateStream(six.Iterator):
             Template('Hello {{ name }}!').stream(name='foo').dump('hello.html')
         """
         close = False
-        if isinstance(fp, six.string_types):
+        if isinstance(fp, string_types):
             fp = open(fp, encoding is None and 'w' or 'wb')
             close = True
         try:
@@ -1143,7 +1143,7 @@ class TemplateStream(six.Iterator):
 
     def disable_buffering(self):
         """Disable the output buffering."""
-        self._next = lambda: six.next(self._gen)
+        self._next = lambda: next(self._gen)
         self.buffered = False
 
     def enable_buffering(self, size=5):
@@ -1171,7 +1171,7 @@ class TemplateStream(six.Iterator):
                 c_size = 0
 
         self.buffered = True
-        self._next = lambda: six.next(generator(lambda: six.next(self._gen)))
+        self._next = lambda: next(generator(lambda: next(self._gen)))
 
     def __iter__(self):
         return self
index 9fe698b576b213098fb7affb2ed317c7d9a84951..0075be00aaa5aae971c1ae0eb348a6214bba8184 100644 (file)
@@ -9,8 +9,7 @@
     :license: BSD, see LICENSE for more details.
 """
 import sys
-import six
-from six.moves import map
+from jinja2._compat import imap, text_type, PY3
 
 
 class TemplateError(Exception):
@@ -19,7 +18,7 @@ class TemplateError(Exception):
     if sys.version_info[0] < 3:
         def __init__(self, message=None):
             if message is not None:
-                message = six.text_type(message).encode('utf-8')
+                message = text_type(message).encode('utf-8')
             Exception.__init__(self, message)
 
         @property
@@ -75,7 +74,7 @@ class TemplatesNotFound(TemplateNotFound):
     def __init__(self, names=(), message=None):
         if message is None:
             message = u'none of the templates given were found: ' + \
-                      u', '.join(map(six.text_type, names))
+                      u', '.join(imap(text_type, names))
         TemplateNotFound.__init__(self, names and names[-1] or None, message)
         self.templates = list(names)
 
@@ -94,10 +93,6 @@ class TemplateSyntaxError(TemplateError):
         # function translated the syntax error into a new traceback
         self.translated = False
 
-    def __str__(self):
-        s = self.__unicode__()
-        return s if six.PY3 else s.encode('utf-8')
-
     def __unicode__(self):
         # for translated errors we only return the message
         if self.translated:
@@ -121,6 +116,13 @@ class TemplateSyntaxError(TemplateError):
 
         return u'\n'.join(lines)
 
+    if PY3:
+        __str__ = __unicode__
+        del __unicode__
+    else:
+        def __str__(self):
+            return self.__unicode__().encode('utf-8')
+
 
 class TemplateAssertionError(TemplateSyntaxError):
     """Like a template syntax error, but covers cases where something in the
index 8ded3d12fb418333443d5fc14711c53148660c88..a88c088dba3c241887e85f785b7bc83553939d0b 100644 (file)
@@ -20,8 +20,7 @@ from jinja2.environment import Environment
 from jinja2.runtime import concat
 from jinja2.exceptions import TemplateAssertionError, TemplateSyntaxError
 from jinja2.utils import contextfunction, import_string, Markup
-from jinja2._compat import next
-import six
+from jinja2._compat import next, with_metaclass, string_types, iteritems
 
 
 # the only real useful gettext functions for a Jinja template.  Note
@@ -39,7 +38,7 @@ class ExtensionRegistry(type):
         return rv
 
 
-class Extension(six.with_metaclass(ExtensionRegistry, object)):
+class Extension(with_metaclass(ExtensionRegistry, object)):
     """Extensions can be used to add extra functionality to the Jinja template
     system at the parser level.  Custom extensions are bound to an environment
     but may not store environment specific data on `self`.  The reason for
@@ -210,7 +209,7 @@ class InternationalizationExtension(Extension):
             self.environment.globals.pop(key, None)
 
     def _extract(self, source, gettext_functions=GETTEXT_FUNCTIONS):
-        if isinstance(source, six.string_types):
+        if isinstance(source, string_types):
             source = self.environment.parse(source)
         return extract_from_ast(source, gettext_functions)
 
@@ -369,7 +368,7 @@ class InternationalizationExtension(Extension):
         # enough to handle the variable expansion and autoescape
         # handling itself
         if self.environment.newstyle_gettext:
-            for key, value in six.iteritems(variables):
+            for key, value in iteritems(variables):
                 # the function adds that later anyways in case num was
                 # called num, so just skip it.
                 if num_called_num and key == 'num':
@@ -491,7 +490,7 @@ def extract_from_ast(node, gettext_functions=GETTEXT_FUNCTIONS,
         strings = []
         for arg in node.args:
             if isinstance(arg, nodes.Const) and \
-               isinstance(arg.value, six.string_types):
+               isinstance(arg.value, string_types):
                 strings.append(arg.value)
             else:
                 strings.append(None)
index f0fbb385a3410d986a0659907c1110613f9f2480..2f6ffd07a4084b6a9e3624ade3515f768d6f51e9 100644 (file)
@@ -10,7 +10,6 @@
 """
 import re
 import math
-import six
 
 from random import choice
 from operator import itemgetter
@@ -19,8 +18,7 @@ from jinja2.utils import Markup, escape, pformat, urlize, soft_unicode, \
      unicode_urlencode
 from jinja2.runtime import Undefined
 from jinja2.exceptions import FilterArgumentError
-from jinja2._compat import next
-from six.moves import map
+from jinja2._compat import next, imap, string_types, text_type, iteritems
 
 
 _word_re = re.compile(r'\w+(?u)')
@@ -58,7 +56,7 @@ def make_attrgetter(environment, attribute):
     passed object with the rules of the environment.  Dots are allowed
     to access attributes of attributes.
     """
-    if not isinstance(attribute, six.string_types) or '.' not in attribute:
+    if not isinstance(attribute, string_types) or '.' not in attribute:
         return lambda x: environment.getitem(x, attribute)
     attribute = attribute.split('.')
     def attrgetter(item):
@@ -72,7 +70,7 @@ def do_forceescape(value):
     """Enforce HTML escaping.  This will probably double escape variables."""
     if hasattr(value, '__html__'):
         value = value.__html__()
-    return escape(six.text_type(value))
+    return escape(text_type(value))
 
 
 def do_urlencode(value):
@@ -83,8 +81,8 @@ def do_urlencode(value):
     """
     itemiter = None
     if isinstance(value, dict):
-        itemiter = six.iteritems(value)
-    elif not isinstance(value, six.string_types):
+        itemiter = iteritems(value)
+    elif not isinstance(value, string_types):
         try:
             itemiter = iter(value)
         except TypeError:
@@ -114,7 +112,7 @@ def do_replace(eval_ctx, s, old, new, count=None):
     if count is None:
         count = -1
     if not eval_ctx.autoescape:
-        return six.text_type(s).replace(six.text_type(old), six.text_type(new), count)
+        return text_type(s).replace(text_type(old), text_type(new), count)
     if hasattr(old, '__html__') or hasattr(new, '__html__') and \
        not hasattr(s, '__html__'):
         s = escape(s)
@@ -159,7 +157,7 @@ def do_xmlattr(_eval_ctx, d, autospace=True):
     """
     rv = u' '.join(
         u'%s="%s"' % (escape(key), escape(value))
-        for key, value in six.iteritems(d)
+        for key, value in iteritems(d)
         if value is not None and not isinstance(value, Undefined)
     )
     if autospace and rv:
@@ -214,7 +212,7 @@ def do_dictsort(value, case_sensitive=False, by='key'):
                                   '"key" or "value"')
     def sort_func(item):
         value = item[pos]
-        if isinstance(value, six.string_types) and not case_sensitive:
+        if isinstance(value, string_types) and not case_sensitive:
             value = value.lower()
         return value
 
@@ -251,7 +249,7 @@ def do_sort(environment, value, reverse=False, case_sensitive=False,
     """
     if not case_sensitive:
         def sort_func(item):
-            if isinstance(item, six.string_types):
+            if isinstance(item, string_types):
                 item = item.lower()
             return item
     else:
@@ -309,11 +307,11 @@ def do_join(eval_ctx, value, d=u'', attribute=None):
        The `attribute` parameter was added.
     """
     if attribute is not None:
-        value = map(make_attrgetter(eval_ctx.environment, attribute), value)
+        value = imap(make_attrgetter(eval_ctx.environment, attribute), value)
 
     # no automatic escaping?  joining is a lot eaiser then
     if not eval_ctx.autoescape:
-        return six.text_type(d).join(map(six.text_type, value))
+        return text_type(d).join(imap(text_type, value))
 
     # if the delimiter doesn't have an html representation we check
     # if any of the items has.  If yes we do a coercion to Markup
@@ -324,20 +322,20 @@ def do_join(eval_ctx, value, d=u'', attribute=None):
             if hasattr(item, '__html__'):
                 do_escape = True
             else:
-                value[idx] = six.text_type(item)
+                value[idx] = text_type(item)
         if do_escape:
             d = escape(d)
         else:
-            d = six.text_type(d)
+            d = text_type(d)
         return d.join(value)
 
     # no html involved, to normal joining
-    return soft_unicode(d).join(map(soft_unicode, value))
+    return soft_unicode(d).join(imap(soft_unicode, value))
 
 
 def do_center(value, width=80):
     """Centers the value in a field of a given width."""
-    return six.text_type(value).center(width)
+    return text_type(value).center(width)
 
 
 @environmentfilter
@@ -552,7 +550,7 @@ def do_striptags(value):
     """
     if hasattr(value, '__html__'):
         value = value.__html__()
-    return Markup(six.text_type(value)).striptags()
+    return Markup(text_type(value)).striptags()
 
 
 def do_slice(value, slices, fill_with=None):
@@ -727,7 +725,7 @@ def do_sum(environment, iterable, attribute=None, start=0):
        attributes.  Also the `start` parameter was moved on to the right.
     """
     if attribute is not None:
-        iterable = map(make_attrgetter(environment, attribute), iterable)
+        iterable = imap(make_attrgetter(environment, attribute), iterable)
     return sum(iterable, start)
 
 
@@ -747,14 +745,14 @@ def do_mark_safe(value):
 
 def do_mark_unsafe(value):
     """Mark a value as unsafe.  This is the reverse operation for :func:`safe`."""
-    return six.text_type(value)
+    return text_type(value)
 
 
 def do_reverse(value):
     """Reverse the object or return an iterator the iterates over it the other
     way round.
     """
-    if isinstance(value, six.string_types):
+    if isinstance(value, string_types):
         return value[::-1]
     try:
         return reversed(value)
index 07cf5c606d40bcc4fcc6e3c2791df217fd106020..87e092031803ba1277aef13fc4bea6c57845c472 100644 (file)
     :license: BSD, see LICENSE for more details.
 """
 import re
-import six
 
 from operator import itemgetter
 from collections import deque
 from jinja2.exceptions import TemplateSyntaxError
 from jinja2.utils import LRUCache
-from jinja2._compat import next
+from jinja2._compat import next, iteritems, Iterator, text_type
 
 
 # cache for the lexers. Exists in order to be able to have multiple
@@ -135,7 +134,7 @@ operators = {
     ';':            TOKEN_SEMICOLON
 }
 
-reverse_operators = dict([(v, k) for k, v in six.iteritems(operators)])
+reverse_operators = dict([(v, k) for k, v in iteritems(operators)])
 assert len(operators) == len(reverse_operators), 'operators dropped'
 operator_re = re.compile('(%s)' % '|'.join(re.escape(x) for x in
                          sorted(operators, key=lambda x: -len(x))))
@@ -271,7 +270,7 @@ class Token(tuple):
         )
 
 
-class TokenStreamIterator(six.Iterator):
+class TokenStreamIterator(Iterator):
     """The iterator for tokenstreams.  Iterate over the stream
     until the eof token is reached.
     """
@@ -291,7 +290,7 @@ class TokenStreamIterator(six.Iterator):
         return token
 
 
-class TokenStream(six.Iterator):
+class TokenStream(Iterator):
     """A token stream is an iterable that yields :class:`Token`\s.  The
     parser however does not iterate over it but calls :meth:`next` to go
     one token ahead.  The current active token is stored as :attr:`current`.
@@ -598,7 +597,7 @@ class Lexer(object):
         """This method tokenizes the text and returns the tokens in a
         generator.  Use this method if you just want to tokenize a template.
         """
-        source = six.text_type(source)
+        source = text_type(source)
         lines = source.splitlines()
         if self.keep_trailing_newline and source:
             for newline in ('\r\n', '\r', '\n'):
@@ -646,7 +645,7 @@ class Lexer(object):
                         # yield for the current token the first named
                         # group that matched
                         elif token == '#bygroup':
-                            for key, value in six.iteritems(m.groupdict()):
+                            for key, value in iteritems(m.groupdict()):
                                 if value is not None:
                                     yield lineno, key, value
                                     lineno += value.count('\n')
@@ -703,7 +702,7 @@ class Lexer(object):
                         stack.pop()
                     # resolve the new state by group checking
                     elif new_state == '#bygroup':
-                        for key, value in six.iteritems(m.groupdict()):
+                        for key, value in iteritems(m.groupdict()):
                             if value is not None:
                                 stack.append(key)
                                 break
index f8e4f993b4657bf7f81040ce7fe022473919589d..a9a2625274c28c36125ecd01f70601194e36d6a1 100644 (file)
@@ -13,13 +13,10 @@ import sys
 import weakref
 from types import ModuleType
 from os import path
-import six
-try:
-    from hashlib import sha1
-except ImportError:
-    from sha import new as sha1
+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):
@@ -154,7 +151,7 @@ class FileSystemLoader(BaseLoader):
     """
 
     def __init__(self, searchpath, encoding='utf-8'):
-        if isinstance(searchpath, six.string_types):
+        if isinstance(searchpath, string_types):
             searchpath = [searchpath]
         self.searchpath = list(searchpath)
         self.encoding = encoding
@@ -307,7 +304,7 @@ class FunctionLoader(BaseLoader):
         rv = self.load_func(template)
         if rv is None:
             raise TemplateNotFound(template)
-        elif isinstance(rv, six.string_types):
+        elif isinstance(rv, string_types):
             return rv, None, None
         return rv
 
@@ -360,7 +357,7 @@ class PrefixLoader(BaseLoader):
 
     def list_templates(self):
         result = []
-        for prefix, loader in six.iteritems(self.mapping):
+        for prefix, loader in iteritems(self.mapping):
             for template in loader.list_templates():
                 result.append(prefix + self.delimiter + template)
         return result
@@ -432,7 +429,7 @@ class ModuleLoader(BaseLoader):
         # create a fake module that looks for the templates in the
         # path given.
         mod = _TemplateModule(package_name)
-        if isinstance(path, six.string_types):
+        if isinstance(path, string_types):
             path = [path]
         else:
             path = list(path)
index 26ae0b93d02f834bf27ed0de3bf2344aebea31fb..3110cff6066a0160df1b01c63b117afd60245288 100644 (file)
@@ -11,7 +11,8 @@
 """
 from jinja2 import nodes
 from jinja2.compiler import CodeGenerator
-import six
+from jinja2._compat import string_types
+
 
 class TrackingCodeGenerator(CodeGenerator):
     """We abuse the code generator for introspection."""
@@ -77,7 +78,7 @@ def find_referenced_templates(ast):
                     # something const, only yield the strings and ignore
                     # non-string consts that really just make no sense
                     if isinstance(template_name, nodes.Const):
-                        if isinstance(template_name.value, six.string_types):
+                        if isinstance(template_name.value, string_types):
                             yield template_name.value
                     # something dynamic in there
                     else:
@@ -87,7 +88,7 @@ def find_referenced_templates(ast):
                 yield None
             continue
         # constant is a basestring, direct template name
-        if isinstance(node.template.value, six.string_types):
+        if isinstance(node.template.value, string_types):
             yield node.template.value
         # a tuple or list (latter *should* not happen) made of consts,
         # yield the consts that are strings.  We could warn here for
@@ -95,7 +96,7 @@ def find_referenced_templates(ast):
         elif isinstance(node, nodes.Include) and \
              isinstance(node.template.value, (tuple, list)):
             for template_name in node.template.value:
-                if isinstance(template_name, six.string_types):
+                if isinstance(template_name, string_types):
                     yield template_name
         # something else we don't care about, we could warn here
         else:
index e276f7ef1ff6cc9af3e70809c1acfd4a86de41cf..26ba34830739998bd2fd280b89b56a5cd3322e0a 100644 (file)
     :copyright: (c) 2010 by the Jinja Team.
     :license: BSD, see LICENSE for more details.
 """
-import six
 import operator
 
 from collections import deque
-from jinja2.utils import Markup, MethodType, FunctionType
-from jinja2._compat import next
-from six.moves import zip
+from jinja2.utils import Markup
+from jinja2._compat import next, izip, with_metaclass, text_type, \
+     method_type, function_type
 
 
 #: the types we support for context functions
-_context_function_types = (FunctionType, MethodType)
+_context_function_types = (function_type, method_type)
 
 
 _binop_to_func = {
@@ -105,7 +104,7 @@ def get_eval_context(node, ctx):
     return ctx
 
 
-class Node(six.with_metaclass(NodeType, object)):
+class Node(with_metaclass(NodeType, object)):
     """Baseclass for all Jinja2 nodes.  There are a number of nodes available
     of different types.  There are four major types:
 
@@ -139,7 +138,7 @@ class Node(six.with_metaclass(NodeType, object)):
                     len(self.fields),
                     len(self.fields) != 1 and 's' or ''
                 ))
-            for name, arg in zip(self.fields, fields):
+            for name, arg in izip(self.fields, fields):
                 setattr(self, name, arg)
         for attr in self.attributes:
             setattr(self, attr, attributes.pop(attr, None))
@@ -690,7 +689,7 @@ class Concat(Expr):
 
     def as_const(self, eval_ctx=None):
         eval_ctx = get_eval_context(self, eval_ctx)
-        return ''.join(six.text_type(x.as_const(eval_ctx)) for x in self.nodes)
+        return ''.join(text_type(x.as_const(eval_ctx)) for x in self.nodes)
 
 
 class Compare(Expr):
index f2c47199f9ce0720d48383980ac5edc1ed92ae9a..489bcca79c6ae6f8f163c5ba29ec943a2a7bc844 100644 (file)
@@ -14,9 +14,8 @@ from jinja2.utils import Markup, soft_unicode, escape, missing, concat, \
      internalcode, object_type_repr
 from jinja2.exceptions import UndefinedError, TemplateRuntimeError, \
      TemplateNotFound
-from jinja2._compat import next
-import six
-from six.moves import map
+from jinja2._compat import next, imap, text_type, iteritems, Iterator, \
+     string_types, PY3
 
 
 # these variables are exported to the template runtime
@@ -42,7 +41,7 @@ _last_iteration = object()
 def markup_join(seq):
     """Concatenation that escapes if necessary and converts to unicode."""
     buf = []
-    iterator = map(soft_unicode, seq)
+    iterator = imap(soft_unicode, seq)
     for arg in iterator:
         buf.append(arg)
         if hasattr(arg, '__html__'):
@@ -52,7 +51,7 @@ def markup_join(seq):
 
 def unicode_join(seq):
     """Simple args to unicode conversion and concatenation."""
-    return concat(map(six.text_type, seq))
+    return concat(imap(text_type, seq))
 
 
 def new_context(environment, template_name, blocks, vars=None,
@@ -69,7 +68,7 @@ def new_context(environment, template_name, blocks, vars=None,
         # we don't want to modify the dict passed
         if shared:
             parent = dict(parent)
-        for key, value in six.iteritems(locals):
+        for key, value in iteritems(locals):
             if key[:2] == 'l_' and value is not missing:
                 parent[key[2:]] = value
     return Context(environment, parent, template_name, blocks)
@@ -125,7 +124,7 @@ class Context(object):
         # create the initial mapping of blocks.  Whenever template inheritance
         # takes place the runtime will update this mapping with the new blocks
         # from the template.
-        self.blocks = dict((k, [v]) for k, v in six.iteritems(blocks))
+        self.blocks = dict((k, [v]) for k, v in iteritems(blocks))
 
     def super(self, name, current):
         """Render a parent block."""
@@ -208,7 +207,7 @@ class Context(object):
                               self.parent, True, None, locals)
         context.vars.update(self.vars)
         context.eval_ctx = self.eval_ctx
-        context.blocks.update((k, list(v)) for k, v in six.iteritems(self.blocks))
+        context.blocks.update((k, list(v)) for k, v in iteritems(self.blocks))
         return context
 
     def _all(meth):
@@ -357,7 +356,7 @@ class LoopContext(object):
         )
 
 
-class LoopContextIterator(six.Iterator):
+class LoopContextIterator(Iterator):
     """The iterator for a loop context."""
     __slots__ = ('context',)
 
@@ -472,7 +471,7 @@ class Undefined(object):
         if self._undefined_hint is None:
             if self._undefined_obj is missing:
                 hint = '%r is undefined' % self._undefined_name
-            elif not isinstance(self._undefined_name, six.string_types):
+            elif not isinstance(self._undefined_name, string_types):
                 hint = '%s has no element %r' % (
                     object_type_repr(self._undefined_obj),
                     self._undefined_name
@@ -499,13 +498,16 @@ class Undefined(object):
     __float__ = __complex__ = __pow__ = __rpow__ = \
         _fail_with_undefined_error
 
-    def __str__(self):
-        s = self.__unicode__()
-        return s if six.PY3 else s.encode('utf-8')
-
     def __unicode__(self):
         return u''
 
+    if PY3:
+        __str__ = __unicode__
+        del __unicode__
+    else:
+        def __str__(self):
+            return self.__unicode__().encode('utf-8')
+
     def __len__(self):
         return 0
 
@@ -535,10 +537,6 @@ class DebugUndefined(Undefined):
     """
     __slots__ = ()
 
-    def __str__(self):
-        s = self.__unicode__()
-        return s if six.PY3 else s.encode('utf-8')
-
     def __unicode__(self):
         if self._undefined_hint is None:
             if self._undefined_obj is missing:
@@ -549,6 +547,10 @@ class DebugUndefined(Undefined):
             )
         return u'{{ undefined value printed: %s }}' % self._undefined_hint
 
+    if PY3:
+        __str__ = __unicode__
+        del __unicode__
+
 
 class StrictUndefined(Undefined):
     """An undefined that barks on print and iteration as well as boolean
@@ -570,9 +572,12 @@ class StrictUndefined(Undefined):
     UndefinedError: 'foo' is undefined
     """
     __slots__ = ()
-    __iter__ = __unicode__ = __str__ = __len__ = __nonzero__ = __eq__ = \
+    __iter__ = __str__ = __len__ = __nonzero__ = __eq__ = \
         __ne__ = __bool__ = Undefined._fail_with_undefined_error
 
+    if not PY3:
+        __unicode__ = Undefined._fail_with_undefined_error
+
 
 # remove remaining slots attributes, after the metaclass did the magic they
 # are unneeded and irritating as they contain wrong data for the subclasses.
index ed145d5d28ec36d29d584e2d8c8e72c3d7fe0dcd..68fc59934bb0973213790226925de6461252a196 100644 (file)
     :license: BSD.
 """
 import operator
-import six
 from jinja2.environment import Environment
 from jinja2.exceptions import SecurityError
-from jinja2.utils import FunctionType, MethodType, TracebackType, CodeType, \
-     FrameType, GeneratorType
+from jinja2._compat import string_types, function_type, method_type, \
+     traceback_type, code_type, frame_type, generator_type
 
 
 #: maximum number of items a range may produce
@@ -125,19 +124,19 @@ def is_internal_attribute(obj, attr):
     >>> is_internal_attribute(str, "upper")
     False
     """
-    if isinstance(obj, FunctionType):
+    if isinstance(obj, function_type):
         if attr in UNSAFE_FUNCTION_ATTRIBUTES:
             return True
-    elif isinstance(obj, MethodType):
+    elif isinstance(obj, method_type):
         if attr in UNSAFE_FUNCTION_ATTRIBUTES or \
            attr in UNSAFE_METHOD_ATTRIBUTES:
             return True
     elif isinstance(obj, type):
         if attr == 'mro':
             return True
-    elif isinstance(obj, (CodeType, TracebackType, FrameType)):
+    elif isinstance(obj, (code_type, traceback_type, frame_type)):
         return True
-    elif isinstance(obj, GeneratorType):
+    elif isinstance(obj, generator_type):
         if attr == 'gi_frame':
             return True
     return attr.startswith('__')
@@ -300,7 +299,7 @@ class SandboxedEnvironment(Environment):
         try:
             return obj[argument]
         except (TypeError, LookupError):
-            if isinstance(argument, six.string_types):
+            if isinstance(argument, string_types):
                 try:
                     attr = str(argument)
                 except Exception:
index 140b5bf8276f43c35da5b77a54ddeddc9f099d73..5fff61a55d3d8ba429bd4f68ef3f607910ddbfd1 100644 (file)
 """
 import re
 from jinja2.runtime import Undefined
-import six
-
-try:
-    from collections import Mapping as MappingType
-except ImportError:
-    import UserDict
-    MappingType = (UserDict.UserDict, UserDict.DictMixin, dict)
-
-# nose, nothing here to test
-__test__ = False
+from jinja2._compat import text_type, string_types, mapping_types
 
 
 number_re = re.compile(r'^-?\d+(\.\d+)?$')
@@ -77,17 +68,17 @@ def test_none(value):
 
 def test_lower(value):
     """Return true if the variable is lowercased."""
-    return six.text_type(value).islower()
+    return text_type(value).islower()
 
 
 def test_upper(value):
     """Return true if the variable is uppercased."""
-    return six.text_type(value).isupper()
+    return text_type(value).isupper()
 
 
 def test_string(value):
     """Return true if the object is a string."""
-    return isinstance(value, six.string_types)
+    return isinstance(value, string_types)
 
 
 def test_mapping(value):
@@ -95,7 +86,7 @@ def test_mapping(value):
 
     .. versionadded:: 2.6
     """
-    return isinstance(value, MappingType)
+    return isinstance(value, mapping_types)
 
 
 def test_number(value):
index 164c58334787228791afdf5a99e3f8b82ad3f7cd..f3cf10efde27c692edd2d9566649176a19982530 100644 (file)
@@ -11,8 +11,6 @@
 import re
 import sys
 import errno
-import six
-from six.moves import map
 try:
     from urllib.parse import quote_from_bytes as url_quote
 except ImportError:
@@ -25,6 +23,8 @@ except ImportError:
     except ImportError:
         from dummy_thread import allocate_lock
 from collections import deque
+from jinja2._compat import text_type, string_types, Iterator
+
 
 _word_split_re = re.compile(r'(\s+)')
 _punctuation_re = re.compile(
@@ -67,26 +67,6 @@ else:
 from keyword import iskeyword as is_python_keyword
 
 
-# common types.  These do exist in the special types module too which however
-# does not exist in IronPython out of the box.  Also that way we don't have
-# to deal with implementation specific stuff here
-class _C(object):
-    def method(self): pass
-def _func():
-    yield None
-FunctionType = type(_func)
-GeneratorType = type(_func())
-MethodType = type(_C().method)
-CodeType = type(_C.method.__code__)
-try:
-    raise TypeError()
-except TypeError:
-    _tb = sys.exc_info()[2]
-    TracebackType = type(_tb)
-    FrameType = type(_tb.tb_frame)
-del _C, _tb, _func
-
-
 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
@@ -247,7 +227,7 @@ def urlize(text, trim_url_limit=None, nofollow=False):
     trim_url = lambda x, limit=trim_url_limit: limit is not None \
                          and (x[:limit] + (len(x) >=limit and '...'
                          or '')) or x
-    words = _word_split_re.split(six.text_type(escape(text)))
+    words = _word_split_re.split(text_type(escape(text)))
     nofollow_attr = nofollow and ' rel="nofollow"' or ''
     for i, word in enumerate(words):
         match = _punctuation_re.match(word)
@@ -334,11 +314,11 @@ def unicode_urlencode(obj, charset='utf-8'):
     If non strings are provided they are converted to their unicode
     representation first.
     """
-    if not isinstance(obj, six.string_types):
-        obj = six.text_type(obj)
-    if isinstance(obj, six.text_type):
+    if not isinstance(obj, string_types):
+        obj = text_type(obj)
+    if isinstance(obj, text_type):
         obj = obj.encode(charset)
-    return six.text_type(url_quote(obj))
+    return text_type(url_quote(obj))
 
 
 class LRUCache(object):
@@ -526,7 +506,7 @@ except ImportError:
     pass
 
 
-class Cycler(six.Iterator):
+class Cycler(Iterator):
     """A cycle helper for templates."""
 
     def __init__(self, *items):