1"""
2    Python 2 and 3 compatibility adapted from six.py
3"""
4import sys
5import operator
6import types
7
8PY3 = sys.version_info[0] == 3
9
10
11if PY3:
12    string_types = str,
13    integer_types = int,
14    class_types = type,
15    text_type = str
16    binary_type = bytes
17
18    MAXSIZE = sys.maxsize
19else:
20    string_types = basestring,
21    integer_types = (int, long)
22    class_types = (type, types.ClassType)
23    text_type = unicode
24    binary_type = str
25
26    if sys.platform.startswith("java"):
27        # Jython always uses 32 bits.
28        MAXSIZE = int((1 << 31) - 1)
29    else:
30        # It's possible to have sizeof(long) != sizeof(Py_ssize_t).
31        class X(object):
32
33            def __len__(self):
34                return 1 << 31
35        try:
36            len(X())
37        except OverflowError:
38            # 32-bit
39            MAXSIZE = int((1 << 31) - 1)
40        else:
41            # 64-bit
42            MAXSIZE = int((1 << 63) - 1)
43        del X
44
45
46if PY3:
47    def iterkeys(d, **kw):
48        return iter(d.keys(**kw))
49
50    def itervalues(d, **kw):
51        return iter(d.values(**kw))
52
53    def iteritems(d, **kw):
54        return iter(d.items(**kw))
55
56    def iterlists(d, **kw):
57        return iter(d.lists(**kw))
58
59    viewkeys = operator.methodcaller("keys")
60
61    viewvalues = operator.methodcaller("values")
62
63    viewitems = operator.methodcaller("items")
64else:
65    def iterkeys(d, **kw):
66        return d.iterkeys(**kw)
67
68    def itervalues(d, **kw):
69        return d.itervalues(**kw)
70
71    def iteritems(d, **kw):
72        return d.iteritems(**kw)
73
74    def iterlists(d, **kw):
75        return d.iterlists(**kw)
76
77    viewkeys = operator.methodcaller("viewkeys")
78
79    viewvalues = operator.methodcaller("viewvalues")
80
81    viewitems = operator.methodcaller("viewitems")
82
83
84def with_metaclass(meta, *bases):
85    """Create a base class with a metaclass."""
86    # This requires a bit of explanation: the basic idea is to make a dummy
87    # metaclass for one level of class instantiation that replaces itself with
88    # the actual metaclass.
89    class metaclass(meta):
90
91        def __new__(cls, name, this_bases, d):
92            return meta(name, bases, d)
93    return type.__new__(metaclass, 'temporary_class', (), {})
94