Mercurial > repos > shellac > sam_consensus_v3
comparison env/lib/python3.9/site-packages/attr/_compat.py @ 0:4f3585e2f14b draft default tip
"planemo upload commit 60cee0fc7c0cda8592644e1aad72851dec82c959"
| author | shellac |
|---|---|
| date | Mon, 22 Mar 2021 18:12:50 +0000 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:4f3585e2f14b |
|---|---|
| 1 from __future__ import absolute_import, division, print_function | |
| 2 | |
| 3 import platform | |
| 4 import sys | |
| 5 import types | |
| 6 import warnings | |
| 7 | |
| 8 | |
| 9 PY2 = sys.version_info[0] == 2 | |
| 10 PYPY = platform.python_implementation() == "PyPy" | |
| 11 | |
| 12 | |
| 13 if PYPY or sys.version_info[:2] >= (3, 6): | |
| 14 ordered_dict = dict | |
| 15 else: | |
| 16 from collections import OrderedDict | |
| 17 | |
| 18 ordered_dict = OrderedDict | |
| 19 | |
| 20 | |
| 21 if PY2: | |
| 22 from collections import Mapping, Sequence | |
| 23 | |
| 24 from UserDict import IterableUserDict | |
| 25 | |
| 26 # We 'bundle' isclass instead of using inspect as importing inspect is | |
| 27 # fairly expensive (order of 10-15 ms for a modern machine in 2016) | |
| 28 def isclass(klass): | |
| 29 return isinstance(klass, (type, types.ClassType)) | |
| 30 | |
| 31 # TYPE is used in exceptions, repr(int) is different on Python 2 and 3. | |
| 32 TYPE = "type" | |
| 33 | |
| 34 def iteritems(d): | |
| 35 return d.iteritems() | |
| 36 | |
| 37 # Python 2 is bereft of a read-only dict proxy, so we make one! | |
| 38 class ReadOnlyDict(IterableUserDict): | |
| 39 """ | |
| 40 Best-effort read-only dict wrapper. | |
| 41 """ | |
| 42 | |
| 43 def __setitem__(self, key, val): | |
| 44 # We gently pretend we're a Python 3 mappingproxy. | |
| 45 raise TypeError( | |
| 46 "'mappingproxy' object does not support item assignment" | |
| 47 ) | |
| 48 | |
| 49 def update(self, _): | |
| 50 # We gently pretend we're a Python 3 mappingproxy. | |
| 51 raise AttributeError( | |
| 52 "'mappingproxy' object has no attribute 'update'" | |
| 53 ) | |
| 54 | |
| 55 def __delitem__(self, _): | |
| 56 # We gently pretend we're a Python 3 mappingproxy. | |
| 57 raise TypeError( | |
| 58 "'mappingproxy' object does not support item deletion" | |
| 59 ) | |
| 60 | |
| 61 def clear(self): | |
| 62 # We gently pretend we're a Python 3 mappingproxy. | |
| 63 raise AttributeError( | |
| 64 "'mappingproxy' object has no attribute 'clear'" | |
| 65 ) | |
| 66 | |
| 67 def pop(self, key, default=None): | |
| 68 # We gently pretend we're a Python 3 mappingproxy. | |
| 69 raise AttributeError( | |
| 70 "'mappingproxy' object has no attribute 'pop'" | |
| 71 ) | |
| 72 | |
| 73 def popitem(self): | |
| 74 # We gently pretend we're a Python 3 mappingproxy. | |
| 75 raise AttributeError( | |
| 76 "'mappingproxy' object has no attribute 'popitem'" | |
| 77 ) | |
| 78 | |
| 79 def setdefault(self, key, default=None): | |
| 80 # We gently pretend we're a Python 3 mappingproxy. | |
| 81 raise AttributeError( | |
| 82 "'mappingproxy' object has no attribute 'setdefault'" | |
| 83 ) | |
| 84 | |
| 85 def __repr__(self): | |
| 86 # Override to be identical to the Python 3 version. | |
| 87 return "mappingproxy(" + repr(self.data) + ")" | |
| 88 | |
| 89 def metadata_proxy(d): | |
| 90 res = ReadOnlyDict() | |
| 91 res.data.update(d) # We blocked update, so we have to do it like this. | |
| 92 return res | |
| 93 | |
| 94 def just_warn(*args, **kw): # pragma: no cover | |
| 95 """ | |
| 96 We only warn on Python 3 because we are not aware of any concrete | |
| 97 consequences of not setting the cell on Python 2. | |
| 98 """ | |
| 99 | |
| 100 | |
| 101 else: # Python 3 and later. | |
| 102 from collections.abc import Mapping, Sequence # noqa | |
| 103 | |
| 104 def just_warn(*args, **kw): | |
| 105 """ | |
| 106 We only warn on Python 3 because we are not aware of any concrete | |
| 107 consequences of not setting the cell on Python 2. | |
| 108 """ | |
| 109 warnings.warn( | |
| 110 "Running interpreter doesn't sufficiently support code object " | |
| 111 "introspection. Some features like bare super() or accessing " | |
| 112 "__class__ will not work with slotted classes.", | |
| 113 RuntimeWarning, | |
| 114 stacklevel=2, | |
| 115 ) | |
| 116 | |
| 117 def isclass(klass): | |
| 118 return isinstance(klass, type) | |
| 119 | |
| 120 TYPE = "class" | |
| 121 | |
| 122 def iteritems(d): | |
| 123 return d.items() | |
| 124 | |
| 125 def metadata_proxy(d): | |
| 126 return types.MappingProxyType(dict(d)) | |
| 127 | |
| 128 | |
| 129 def make_set_closure_cell(): | |
| 130 """Return a function of two arguments (cell, value) which sets | |
| 131 the value stored in the closure cell `cell` to `value`. | |
| 132 """ | |
| 133 # pypy makes this easy. (It also supports the logic below, but | |
| 134 # why not do the easy/fast thing?) | |
| 135 if PYPY: | |
| 136 | |
| 137 def set_closure_cell(cell, value): | |
| 138 cell.__setstate__((value,)) | |
| 139 | |
| 140 return set_closure_cell | |
| 141 | |
| 142 # Otherwise gotta do it the hard way. | |
| 143 | |
| 144 # Create a function that will set its first cellvar to `value`. | |
| 145 def set_first_cellvar_to(value): | |
| 146 x = value | |
| 147 return | |
| 148 | |
| 149 # This function will be eliminated as dead code, but | |
| 150 # not before its reference to `x` forces `x` to be | |
| 151 # represented as a closure cell rather than a local. | |
| 152 def force_x_to_be_a_cell(): # pragma: no cover | |
| 153 return x | |
| 154 | |
| 155 try: | |
| 156 # Extract the code object and make sure our assumptions about | |
| 157 # the closure behavior are correct. | |
| 158 if PY2: | |
| 159 co = set_first_cellvar_to.func_code | |
| 160 else: | |
| 161 co = set_first_cellvar_to.__code__ | |
| 162 if co.co_cellvars != ("x",) or co.co_freevars != (): | |
| 163 raise AssertionError # pragma: no cover | |
| 164 | |
| 165 # Convert this code object to a code object that sets the | |
| 166 # function's first _freevar_ (not cellvar) to the argument. | |
| 167 if sys.version_info >= (3, 8): | |
| 168 # CPython 3.8+ has an incompatible CodeType signature | |
| 169 # (added a posonlyargcount argument) but also added | |
| 170 # CodeType.replace() to do this without counting parameters. | |
| 171 set_first_freevar_code = co.replace( | |
| 172 co_cellvars=co.co_freevars, co_freevars=co.co_cellvars | |
| 173 ) | |
| 174 else: | |
| 175 args = [co.co_argcount] | |
| 176 if not PY2: | |
| 177 args.append(co.co_kwonlyargcount) | |
| 178 args.extend( | |
| 179 [ | |
| 180 co.co_nlocals, | |
| 181 co.co_stacksize, | |
| 182 co.co_flags, | |
| 183 co.co_code, | |
| 184 co.co_consts, | |
| 185 co.co_names, | |
| 186 co.co_varnames, | |
| 187 co.co_filename, | |
| 188 co.co_name, | |
| 189 co.co_firstlineno, | |
| 190 co.co_lnotab, | |
| 191 # These two arguments are reversed: | |
| 192 co.co_cellvars, | |
| 193 co.co_freevars, | |
| 194 ] | |
| 195 ) | |
| 196 set_first_freevar_code = types.CodeType(*args) | |
| 197 | |
| 198 def set_closure_cell(cell, value): | |
| 199 # Create a function using the set_first_freevar_code, | |
| 200 # whose first closure cell is `cell`. Calling it will | |
| 201 # change the value of that cell. | |
| 202 setter = types.FunctionType( | |
| 203 set_first_freevar_code, {}, "setter", (), (cell,) | |
| 204 ) | |
| 205 # And call it to set the cell. | |
| 206 setter(value) | |
| 207 | |
| 208 # Make sure it works on this interpreter: | |
| 209 def make_func_with_cell(): | |
| 210 x = None | |
| 211 | |
| 212 def func(): | |
| 213 return x # pragma: no cover | |
| 214 | |
| 215 return func | |
| 216 | |
| 217 if PY2: | |
| 218 cell = make_func_with_cell().func_closure[0] | |
| 219 else: | |
| 220 cell = make_func_with_cell().__closure__[0] | |
| 221 set_closure_cell(cell, 100) | |
| 222 if cell.cell_contents != 100: | |
| 223 raise AssertionError # pragma: no cover | |
| 224 | |
| 225 except Exception: | |
| 226 return just_warn | |
| 227 else: | |
| 228 return set_closure_cell | |
| 229 | |
| 230 | |
| 231 set_closure_cell = make_set_closure_cell() |
