1793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler# -*- coding: utf-8 -*-
2793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler"""
3793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    jinja2._compat
4793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    ~~~~~~~~~~~~~~
5793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
6793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    Some py2/py3 compatibility support based on a stripped down
7793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    version of six so we don't have to depend on a specific version
8793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    of it.
9793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
10793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    :copyright: Copyright 2013 by the Jinja team, see AUTHORS.
11793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    :license: BSD, see LICENSE for details.
12793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler"""
13793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerimport sys
14793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
15793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerPY2 = sys.version_info[0] == 2
16793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerPYPY = hasattr(sys, 'pypy_translation_info')
17793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler_identity = lambda x: x
18793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
19793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
20793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerif not PY2:
21793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    unichr = chr
22793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    range_type = range
23793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    text_type = str
24793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    string_types = (str,)
25793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
26793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    iterkeys = lambda d: iter(d.keys())
27793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    itervalues = lambda d: iter(d.values())
28793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    iteritems = lambda d: iter(d.items())
29793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
30793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    import pickle
31793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    from io import BytesIO, StringIO
32793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    NativeStringIO = StringIO
33793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
34793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    def reraise(tp, value, tb=None):
35793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if value.__traceback__ is not tb:
36793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            raise value.with_traceback(tb)
37793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        raise value
38793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
39793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    ifilter = filter
40793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    imap = map
41793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    izip = zip
42793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    intern = sys.intern
43793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
44793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    implements_iterator = _identity
45793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    implements_to_string = _identity
46793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    encode_filename = _identity
47793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    get_next = lambda x: x.__next__
48793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
49793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerelse:
50793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    unichr = unichr
51793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    text_type = unicode
52793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    range_type = xrange
53793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    string_types = (str, unicode)
54793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
55793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    iterkeys = lambda d: d.iterkeys()
56793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    itervalues = lambda d: d.itervalues()
57793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    iteritems = lambda d: d.iteritems()
58793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
59793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    import cPickle as pickle
60793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    from cStringIO import StringIO as BytesIO, StringIO
61793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    NativeStringIO = BytesIO
62793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
63793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    exec('def reraise(tp, value, tb=None):\n raise tp, value, tb')
64793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
65793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    from itertools import imap, izip, ifilter
66793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    intern = intern
67793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
68793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    def implements_iterator(cls):
69793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cls.next = cls.__next__
70793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        del cls.__next__
71793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return cls
72793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
73793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    def implements_to_string(cls):
74793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cls.__unicode__ = cls.__str__
75793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cls.__str__ = lambda x: x.__unicode__().encode('utf-8')
76793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return cls
77793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
78793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    get_next = lambda x: x.next
79793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
80793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    def encode_filename(filename):
81793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if isinstance(filename, unicode):
82793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            return filename.encode('utf-8')
83793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return filename
84793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
85793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslertry:
86793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    next = next
87793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerexcept NameError:
88793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    def next(it):
89793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return it.next()
90793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
91793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
92793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerdef with_metaclass(meta, *bases):
93793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    # This requires a bit of explanation: the basic idea is to make a
94793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    # dummy metaclass for one level of class instanciation that replaces
95793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    # itself with the actual metaclass.  Because of internal type checks
96793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    # we also need to make sure that we downgrade the custom metaclass
97793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    # for one level to something closer to type (that's why __call__ and
98793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    # __init__ comes back from type etc.).
99793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    #
100793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    # This has the advantage over six.with_metaclass in that it does not
101793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    # introduce dummy classes into the final MRO.
102793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    class metaclass(meta):
103793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        __call__ = type.__call__
104793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        __init__ = type.__init__
105793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        def __new__(cls, name, this_bases, d):
106793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if this_bases is None:
107793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                return type.__new__(cls, name, (), d)
108793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            return meta(name, bases, d)
109793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return metaclass('temporary_class', None, {})
110793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
111793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
112793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslertry:
113793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    from collections import Mapping as mapping_types
114793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerexcept ImportError:
115793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    import UserDict
116793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    mapping_types = (UserDict.UserDict, UserDict.DictMixin, dict)
117793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
118793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
119793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler# common types.  These do exist in the special types module too which however
120793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler# does not exist in IronPython out of the box.  Also that way we don't have
121793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler# to deal with implementation specific stuff here
122793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerclass _C(object):
123793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    def method(self): pass
124793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerdef _func():
125793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    yield None
126793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerfunction_type = type(_func)
127793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslergenerator_type = type(_func())
128793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslermethod_type = type(_C().method)
129793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslercode_type = type(_C.method.__code__)
130793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslertry:
131793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    raise TypeError()
132793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerexcept TypeError:
133793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    _tb = sys.exc_info()[2]
134793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    traceback_type = type(_tb)
135793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    frame_type = type(_tb.tb_frame)
136793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
137793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
138793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslertry:
139793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    from urllib.parse import quote_from_bytes as url_quote
140793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerexcept ImportError:
141793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    from urllib import quote as url_quote
142793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
143793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
144793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslertry:
145793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    from thread import allocate_lock
146793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerexcept ImportError:
147793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    try:
148793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        from threading import Lock as allocate_lock
149793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    except ImportError:
150793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        from dummy_thread import allocate_lock
151