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))
|