1# -*- coding: utf-8 -*-
2"""
3    jinja2._compat
4    ~~~~~~~~~~~~~~
5
6    Some py2/py3 compatibility support based on a stripped down
7    version of six so we don't have to depend on a specific version
8    of it.
9
10    :copyright: Copyright 2013 by the Jinja team, see AUTHORS.
11    :license: BSD, see LICENSE for details.
12"""
13import sys
14
15PY2 = sys.version_info[0] == 2
16PYPY = hasattr(sys, 'pypy_translation_info')
17_identity = lambda x: x
18
19
20if not PY2:
21    unichr = chr
22    range_type = range
23    text_type = str
24    string_types = (str,)
25    integer_types = (int,)
26
27    iterkeys = lambda d: iter(d.keys())
28    itervalues = lambda d: iter(d.values())
29    iteritems = lambda d: iter(d.items())
30
31    import pickle
32    from io import BytesIO, StringIO
33    NativeStringIO = StringIO
34
35    def reraise(tp, value, tb=None):
36        if value.__traceback__ is not tb:
37            raise value.with_traceback(tb)
38        raise value
39
40    ifilter = filter
41    imap = map
42    izip = zip
43    intern = sys.intern
44
45    implements_iterator = _identity
46    implements_to_string = _identity
47    encode_filename = _identity
48
49else:
50    unichr = unichr
51    text_type = unicode
52    range_type = xrange
53    string_types = (str, unicode)
54    integer_types = (int, long)
55
56    iterkeys = lambda d: d.iterkeys()
57    itervalues = lambda d: d.itervalues()
58    iteritems = lambda d: d.iteritems()
59
60    import cPickle as pickle
61    from cStringIO import StringIO as BytesIO, StringIO
62    NativeStringIO = BytesIO
63
64    exec('def reraise(tp, value, tb=None):\n raise tp, value, tb')
65
66    from itertools import imap, izip, ifilter
67    intern = intern
68
69    def implements_iterator(cls):
70        cls.next = cls.__next__
71        del cls.__next__
72        return cls
73
74    def implements_to_string(cls):
75        cls.__unicode__ = cls.__str__
76        cls.__str__ = lambda x: x.__unicode__().encode('utf-8')
77        return cls
78
79    def encode_filename(filename):
80        if isinstance(filename, unicode):
81            return filename.encode('utf-8')
82        return filename
83
84
85def with_metaclass(meta, *bases):
86    """Create a base class with a metaclass."""
87    # This requires a bit of explanation: the basic idea is to make a
88    # dummy metaclass for one level of class instantiation that replaces
89    # itself with the actual metaclass.
90    class metaclass(type):
91        def __new__(cls, name, this_bases, d):
92            return meta(name, bases, d)
93    return type.__new__(metaclass, 'temporary_class', (), {})
94
95
96try:
97    from urllib.parse import quote_from_bytes as url_quote
98except ImportError:
99    from urllib import quote as url_quote
100