1645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez# -*- coding: utf-8 -*-
2645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez"""
3645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    jinja2._compat
4645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ~~~~~~~~~~~~~~
5645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
6645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    Some py2/py3 compatibility support based on a stripped down
7645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    version of six so we don't have to depend on a specific version
8645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    of it.
9645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
10645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    :copyright: Copyright 2013 by the Jinja team, see AUTHORS.
11645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    :license: BSD, see LICENSE for details.
12645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez"""
13645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezimport sys
14645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
15645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector ChavezPY2 = sys.version_info[0] == 2
16645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector ChavezPYPY = hasattr(sys, 'pypy_translation_info')
17645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez_identity = lambda x: x
18645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
19645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
20645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezif not PY2:
21645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    unichr = chr
22645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    range_type = range
23645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    text_type = str
24645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    string_types = (str,)
25645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
26645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    iterkeys = lambda d: iter(d.keys())
27645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    itervalues = lambda d: iter(d.values())
28645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    iteritems = lambda d: iter(d.items())
29645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
30645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    import pickle
31645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    from io import BytesIO, StringIO
32645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    NativeStringIO = StringIO
33645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
34645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    def reraise(tp, value, tb=None):
35645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        if value.__traceback__ is not tb:
36645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            raise value.with_traceback(tb)
37645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        raise value
38645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
39645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    ifilter = filter
40645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    imap = map
41645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    izip = zip
42645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    intern = sys.intern
43645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
44645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    implements_iterator = _identity
45645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    implements_to_string = _identity
46645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    encode_filename = _identity
47645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    get_next = lambda x: x.__next__
48645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
49645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezelse:
50645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    unichr = unichr
51645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    text_type = unicode
52645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    range_type = xrange
53645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    string_types = (str, unicode)
54645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
55645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    iterkeys = lambda d: d.iterkeys()
56645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    itervalues = lambda d: d.itervalues()
57645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    iteritems = lambda d: d.iteritems()
58645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
59645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    import cPickle as pickle
60645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    from cStringIO import StringIO as BytesIO, StringIO
61645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    NativeStringIO = BytesIO
62645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
63645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    exec('def reraise(tp, value, tb=None):\n raise tp, value, tb')
64645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
65645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    from itertools import imap, izip, ifilter
66645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    intern = intern
67645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
68645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    def implements_iterator(cls):
69645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        cls.next = cls.__next__
70645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        del cls.__next__
71645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        return cls
72645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
73645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    def implements_to_string(cls):
74645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        cls.__unicode__ = cls.__str__
75645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        cls.__str__ = lambda x: x.__unicode__().encode('utf-8')
76645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        return cls
77645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
78645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    get_next = lambda x: x.next
79645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
80645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    def encode_filename(filename):
81645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        if isinstance(filename, unicode):
82645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            return filename.encode('utf-8')
83645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        return filename
84645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
85645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chaveztry:
86645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    next = next
87645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezexcept NameError:
88645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    def next(it):
89645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        return it.next()
90645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
91645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
92645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezdef with_metaclass(meta, *bases):
93645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    # This requires a bit of explanation: the basic idea is to make a
94645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    # dummy metaclass for one level of class instanciation that replaces
95645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    # itself with the actual metaclass.  Because of internal type checks
96645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    # we also need to make sure that we downgrade the custom metaclass
97645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    # for one level to something closer to type (that's why __call__ and
98645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    # __init__ comes back from type etc.).
99645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    #
100645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    # This has the advantage over six.with_metaclass in that it does not
101645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    # introduce dummy classes into the final MRO.
102645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    class metaclass(meta):
103645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        __call__ = type.__call__
104645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        __init__ = type.__init__
105645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        def __new__(cls, name, this_bases, d):
106645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            if this_bases is None:
107645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                return type.__new__(cls, name, (), d)
108645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez            return meta(name, bases, d)
109645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    return metaclass('temporary_class', None, {})
110645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
111645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
112645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chaveztry:
113645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    from collections import Mapping as mapping_types
114645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezexcept ImportError:
115645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    import UserDict
116645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    mapping_types = (UserDict.UserDict, UserDict.DictMixin, dict)
117645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
118645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
119645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez# common types.  These do exist in the special types module too which however
120645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez# does not exist in IronPython out of the box.  Also that way we don't have
121645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez# to deal with implementation specific stuff here
122645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezclass _C(object):
123645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    def method(self): pass
124645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezdef _func():
125645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    yield None
126645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezfunction_type = type(_func)
127645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezgenerator_type = type(_func())
128645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezmethod_type = type(_C().method)
129645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezcode_type = type(_C.method.__code__)
130645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chaveztry:
131645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    raise TypeError()
132645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezexcept TypeError:
133645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    _tb = sys.exc_info()[2]
134645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    traceback_type = type(_tb)
135645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    frame_type = type(_tb.tb_frame)
136645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
137645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
138645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chaveztry:
139645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    from urllib.parse import quote_from_bytes as url_quote
140645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezexcept ImportError:
141645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    from urllib import quote as url_quote
142645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
143645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
144645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chaveztry:
145645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    from thread import allocate_lock
146645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezexcept ImportError:
147645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    try:
148645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        from threading import Lock as allocate_lock
149645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    except ImportError:
150645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez        from dummy_thread import allocate_lock
151