34397
|
1 |
from __future__ import absolute_import, division, print_function
|
|
2 |
|
|
3 |
import sys
|
|
4 |
import types
|
|
5 |
|
|
6 |
|
|
7 |
PY2 = sys.version_info[0] == 2
|
|
8 |
|
|
9 |
|
|
10 |
if PY2:
|
|
11 |
from UserDict import IterableUserDict
|
|
12 |
|
|
13 |
# We 'bundle' isclass instead of using inspect as importing inspect is
|
|
14 |
# fairly expensive (order of 10-15 ms for a modern machine in 2016)
|
|
15 |
def isclass(klass):
|
|
16 |
return isinstance(klass, (type, types.ClassType))
|
|
17 |
|
|
18 |
# TYPE is used in exceptions, repr(int) is different on Python 2 and 3.
|
|
19 |
TYPE = "type"
|
|
20 |
|
|
21 |
def iteritems(d):
|
|
22 |
return d.iteritems()
|
|
23 |
|
|
24 |
def iterkeys(d):
|
|
25 |
return d.iterkeys()
|
|
26 |
|
|
27 |
# Python 2 is bereft of a read-only dict proxy, so we make one!
|
|
28 |
class ReadOnlyDict(IterableUserDict):
|
|
29 |
"""
|
|
30 |
Best-effort read-only dict wrapper.
|
|
31 |
"""
|
|
32 |
|
|
33 |
def __setitem__(self, key, val):
|
|
34 |
# We gently pretend we're a Python 3 mappingproxy.
|
|
35 |
raise TypeError("'mappingproxy' object does not support item "
|
|
36 |
"assignment")
|
|
37 |
|
|
38 |
def update(self, _):
|
|
39 |
# We gently pretend we're a Python 3 mappingproxy.
|
|
40 |
raise AttributeError("'mappingproxy' object has no attribute "
|
|
41 |
"'update'")
|
|
42 |
|
|
43 |
def __delitem__(self, _):
|
|
44 |
# We gently pretend we're a Python 3 mappingproxy.
|
|
45 |
raise TypeError("'mappingproxy' object does not support item "
|
|
46 |
"deletion")
|
|
47 |
|
|
48 |
def clear(self):
|
|
49 |
# We gently pretend we're a Python 3 mappingproxy.
|
|
50 |
raise AttributeError("'mappingproxy' object has no attribute "
|
|
51 |
"'clear'")
|
|
52 |
|
|
53 |
def pop(self, key, default=None):
|
|
54 |
# We gently pretend we're a Python 3 mappingproxy.
|
|
55 |
raise AttributeError("'mappingproxy' object has no attribute "
|
|
56 |
"'pop'")
|
|
57 |
|
|
58 |
def popitem(self):
|
|
59 |
# We gently pretend we're a Python 3 mappingproxy.
|
|
60 |
raise AttributeError("'mappingproxy' object has no attribute "
|
|
61 |
"'popitem'")
|
|
62 |
|
|
63 |
def setdefault(self, key, default=None):
|
|
64 |
# We gently pretend we're a Python 3 mappingproxy.
|
|
65 |
raise AttributeError("'mappingproxy' object has no attribute "
|
|
66 |
"'setdefault'")
|
|
67 |
|
|
68 |
def __repr__(self):
|
|
69 |
# Override to be identical to the Python 3 version.
|
|
70 |
return "mappingproxy(" + repr(self.data) + ")"
|
|
71 |
|
|
72 |
def metadata_proxy(d):
|
|
73 |
res = ReadOnlyDict()
|
|
74 |
res.data.update(d) # We blocked update, so we have to do it like this.
|
|
75 |
return res
|
|
76 |
|
|
77 |
else:
|
|
78 |
def isclass(klass):
|
|
79 |
return isinstance(klass, type)
|
|
80 |
|
|
81 |
TYPE = "class"
|
|
82 |
|
|
83 |
def iteritems(d):
|
|
84 |
return d.items()
|
|
85 |
|
|
86 |
def iterkeys(d):
|
|
87 |
return d.keys()
|
|
88 |
|
|
89 |
def metadata_proxy(d):
|
|
90 |
return types.MappingProxyType(dict(d))
|