wrapt 2.0.0rc2__cp314-cp314t-win_arm64.whl → 2.0.1__cp314-cp314t-win_arm64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- wrapt/__init__.py +7 -2
- wrapt/__init__.pyi +23 -3
- wrapt/__wrapt__.py +12 -14
- wrapt/_wrappers.c +1771 -749
- wrapt/_wrappers.cp314t-win_arm64.pyd +0 -0
- wrapt/decorators.py +1 -6
- wrapt/importer.py +2 -2
- wrapt/proxies.py +351 -0
- wrapt/weakrefs.py +2 -2
- wrapt/wrappers.py +134 -30
- wrapt-2.0.1.dist-info/METADATA +216 -0
- wrapt-2.0.1.dist-info/RECORD +18 -0
- wrapt-2.0.0rc2.dist-info/METADATA +0 -198
- wrapt-2.0.0rc2.dist-info/RECORD +0 -17
- {wrapt-2.0.0rc2.dist-info → wrapt-2.0.1.dist-info}/WHEEL +0 -0
- {wrapt-2.0.0rc2.dist-info → wrapt-2.0.1.dist-info}/licenses/LICENSE +0 -0
- {wrapt-2.0.0rc2.dist-info → wrapt-2.0.1.dist-info}/top_level.txt +0 -0
|
Binary file
|
wrapt/decorators.py
CHANGED
|
@@ -8,12 +8,7 @@ from functools import partial
|
|
|
8
8
|
from inspect import isclass, signature
|
|
9
9
|
from threading import Lock, RLock
|
|
10
10
|
|
|
11
|
-
from .__wrapt__ import
|
|
12
|
-
BoundFunctionWrapper,
|
|
13
|
-
CallableObjectProxy,
|
|
14
|
-
FunctionWrapper,
|
|
15
|
-
ObjectProxy,
|
|
16
|
-
)
|
|
11
|
+
from .__wrapt__ import BoundFunctionWrapper, CallableObjectProxy, FunctionWrapper
|
|
17
12
|
from .arguments import formatargspec
|
|
18
13
|
|
|
19
14
|
# Adapter wrapper for the wrapped function which will overlay certain
|
wrapt/importer.py
CHANGED
|
@@ -9,7 +9,7 @@ import threading
|
|
|
9
9
|
from importlib.util import find_spec
|
|
10
10
|
from typing import Callable, Dict, List
|
|
11
11
|
|
|
12
|
-
from .__wrapt__ import
|
|
12
|
+
from .__wrapt__ import BaseObjectProxy
|
|
13
13
|
|
|
14
14
|
# The dictionary registering any post import hooks to be triggered once
|
|
15
15
|
# the target module has been imported. Once a module has been imported
|
|
@@ -166,7 +166,7 @@ class _ImportHookLoader:
|
|
|
166
166
|
return module
|
|
167
167
|
|
|
168
168
|
|
|
169
|
-
class _ImportHookChainedLoader(
|
|
169
|
+
class _ImportHookChainedLoader(BaseObjectProxy):
|
|
170
170
|
|
|
171
171
|
def __init__(self, loader):
|
|
172
172
|
super(_ImportHookChainedLoader, self).__init__(loader)
|
wrapt/proxies.py
ADDED
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
"""Variants of ObjectProxy for different use cases."""
|
|
2
|
+
|
|
3
|
+
from collections.abc import Callable
|
|
4
|
+
from types import ModuleType
|
|
5
|
+
|
|
6
|
+
from .__wrapt__ import BaseObjectProxy
|
|
7
|
+
from .decorators import synchronized
|
|
8
|
+
|
|
9
|
+
# Define ObjectProxy which for compatibility adds `__iter__()` support which
|
|
10
|
+
# has been removed from `BaseObjectProxy`.
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class ObjectProxy(BaseObjectProxy):
|
|
14
|
+
"""A generic object proxy which forwards special methods as needed.
|
|
15
|
+
For backwards compatibility this class adds support for `__iter__()`. If
|
|
16
|
+
you don't need backward compatibility for `__iter__()` support then it is
|
|
17
|
+
preferable to use `BaseObjectProxy` directly. If you want automatic
|
|
18
|
+
support for special dunder methods for callables, iterators, and async,
|
|
19
|
+
then use `AutoObjectProxy`."""
|
|
20
|
+
|
|
21
|
+
@property
|
|
22
|
+
def __object_proxy__(self):
|
|
23
|
+
return ObjectProxy
|
|
24
|
+
|
|
25
|
+
def __new__(cls, *args, **kwargs):
|
|
26
|
+
return super().__new__(cls)
|
|
27
|
+
|
|
28
|
+
def __iter__(self):
|
|
29
|
+
return iter(self.__wrapped__)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
# Define variant of ObjectProxy which can automatically adjust to the wrapped
|
|
33
|
+
# object and add special dunder methods.
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def __wrapper_call__(*args, **kwargs):
|
|
37
|
+
def _unpack_self(self, *args):
|
|
38
|
+
return self, args
|
|
39
|
+
|
|
40
|
+
self, args = _unpack_self(*args)
|
|
41
|
+
|
|
42
|
+
return self.__wrapped__(*args, **kwargs)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def __wrapper_iter__(self):
|
|
46
|
+
return iter(self.__wrapped__)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def __wrapper_next__(self):
|
|
50
|
+
return self.__wrapped__.__next__()
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def __wrapper_aiter__(self):
|
|
54
|
+
return self.__wrapped__.__aiter__()
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
async def __wrapper_anext__(self):
|
|
58
|
+
return await self.__wrapped__.__anext__()
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def __wrapper_length_hint__(self):
|
|
62
|
+
return self.__wrapped__.__length_hint__()
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def __wrapper_await__(self):
|
|
66
|
+
return (yield from self.__wrapped__.__await__())
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def __wrapper_get__(self, instance, owner):
|
|
70
|
+
return self.__wrapped__.__get__(instance, owner)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def __wrapper_set__(self, instance, value):
|
|
74
|
+
return self.__wrapped__.__set__(instance, value)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def __wrapper_delete__(self, instance):
|
|
78
|
+
return self.__wrapped__.__delete__(instance)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def __wrapper_set_name__(self, owner, name):
|
|
82
|
+
return self.__wrapped__.__set_name__(owner, name)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
class AutoObjectProxy(BaseObjectProxy):
|
|
86
|
+
"""An object proxy which can automatically adjust to the wrapped object
|
|
87
|
+
and add special dunder methods as needed. Note that this creates a new
|
|
88
|
+
class for each instance, so it has much higher memory overhead than using
|
|
89
|
+
`BaseObjectProxy` directly. If you know what special dunder methods you need
|
|
90
|
+
then it is preferable to use `BaseObjectProxy` directly and add them to a
|
|
91
|
+
subclass as needed. If you only need `__iter__()` support for backwards
|
|
92
|
+
compatibility then use `ObjectProxy` instead.
|
|
93
|
+
"""
|
|
94
|
+
|
|
95
|
+
def __new__(cls, wrapped):
|
|
96
|
+
"""Injects special dunder methods into a dynamically created subclass
|
|
97
|
+
as needed based on the wrapped object.
|
|
98
|
+
"""
|
|
99
|
+
|
|
100
|
+
namespace = {}
|
|
101
|
+
|
|
102
|
+
wrapped_attrs = dir(wrapped)
|
|
103
|
+
class_attrs = set(dir(cls))
|
|
104
|
+
|
|
105
|
+
if callable(wrapped) and "__call__" not in class_attrs:
|
|
106
|
+
namespace["__call__"] = __wrapper_call__
|
|
107
|
+
|
|
108
|
+
if "__iter__" in wrapped_attrs and "__iter__" not in class_attrs:
|
|
109
|
+
namespace["__iter__"] = __wrapper_iter__
|
|
110
|
+
|
|
111
|
+
if "__next__" in wrapped_attrs and "__next__" not in class_attrs:
|
|
112
|
+
namespace["__next__"] = __wrapper_next__
|
|
113
|
+
|
|
114
|
+
if "__aiter__" in wrapped_attrs and "__aiter__" not in class_attrs:
|
|
115
|
+
namespace["__aiter__"] = __wrapper_aiter__
|
|
116
|
+
|
|
117
|
+
if "__anext__" in wrapped_attrs and "__anext__" not in class_attrs:
|
|
118
|
+
namespace["__anext__"] = __wrapper_anext__
|
|
119
|
+
|
|
120
|
+
if "__length_hint__" in wrapped_attrs and "__length_hint__" not in class_attrs:
|
|
121
|
+
namespace["__length_hint__"] = __wrapper_length_hint__
|
|
122
|
+
|
|
123
|
+
# Note that not providing compatibility with generator-based coroutines
|
|
124
|
+
# (PEP 342) here as they are removed in Python 3.11+ and were deprecated
|
|
125
|
+
# in 3.8.
|
|
126
|
+
|
|
127
|
+
if "__await__" in wrapped_attrs and "__await__" not in class_attrs:
|
|
128
|
+
namespace["__await__"] = __wrapper_await__
|
|
129
|
+
|
|
130
|
+
if "__get__" in wrapped_attrs and "__get__" not in class_attrs:
|
|
131
|
+
namespace["__get__"] = __wrapper_get__
|
|
132
|
+
|
|
133
|
+
if "__set__" in wrapped_attrs and "__set__" not in class_attrs:
|
|
134
|
+
namespace["__set__"] = __wrapper_set__
|
|
135
|
+
|
|
136
|
+
if "__delete__" in wrapped_attrs and "__delete__" not in class_attrs:
|
|
137
|
+
namespace["__delete__"] = __wrapper_delete__
|
|
138
|
+
|
|
139
|
+
if "__set_name__" in wrapped_attrs and "__set_name__" not in class_attrs:
|
|
140
|
+
namespace["__set_name__"] = __wrapper_set_name__
|
|
141
|
+
|
|
142
|
+
name = cls.__name__
|
|
143
|
+
|
|
144
|
+
if cls is AutoObjectProxy:
|
|
145
|
+
name = BaseObjectProxy.__name__
|
|
146
|
+
|
|
147
|
+
return super(AutoObjectProxy, cls).__new__(type(name, (cls,), namespace))
|
|
148
|
+
|
|
149
|
+
def __wrapped_setattr_fixups__(self):
|
|
150
|
+
"""Adjusts special dunder methods on the class as needed based on the
|
|
151
|
+
wrapped object, when `__wrapped__` is changed.
|
|
152
|
+
"""
|
|
153
|
+
|
|
154
|
+
cls = type(self)
|
|
155
|
+
class_attrs = set(dir(cls))
|
|
156
|
+
|
|
157
|
+
if callable(self.__wrapped__):
|
|
158
|
+
if "__call__" not in class_attrs:
|
|
159
|
+
cls.__call__ = __wrapper_call__
|
|
160
|
+
elif getattr(cls, "__call__", None) is __wrapper_call__:
|
|
161
|
+
delattr(cls, "__call__")
|
|
162
|
+
|
|
163
|
+
if hasattr(self.__wrapped__, "__iter__"):
|
|
164
|
+
if "__iter__" not in class_attrs:
|
|
165
|
+
cls.__iter__ = __wrapper_iter__
|
|
166
|
+
elif getattr(cls, "__iter__", None) is __wrapper_iter__:
|
|
167
|
+
delattr(cls, "__iter__")
|
|
168
|
+
|
|
169
|
+
if hasattr(self.__wrapped__, "__next__"):
|
|
170
|
+
if "__next__" not in class_attrs:
|
|
171
|
+
cls.__next__ = __wrapper_next__
|
|
172
|
+
elif getattr(cls, "__next__", None) is __wrapper_next__:
|
|
173
|
+
delattr(cls, "__next__")
|
|
174
|
+
|
|
175
|
+
if hasattr(self.__wrapped__, "__aiter__"):
|
|
176
|
+
if "__aiter__" not in class_attrs:
|
|
177
|
+
cls.__aiter__ = __wrapper_aiter__
|
|
178
|
+
elif getattr(cls, "__aiter__", None) is __wrapper_aiter__:
|
|
179
|
+
delattr(cls, "__aiter__")
|
|
180
|
+
|
|
181
|
+
if hasattr(self.__wrapped__, "__anext__"):
|
|
182
|
+
if "__anext__" not in class_attrs:
|
|
183
|
+
cls.__anext__ = __wrapper_anext__
|
|
184
|
+
elif getattr(cls, "__anext__", None) is __wrapper_anext__:
|
|
185
|
+
delattr(cls, "__anext__")
|
|
186
|
+
|
|
187
|
+
if hasattr(self.__wrapped__, "__length_hint__"):
|
|
188
|
+
if "__length_hint__" not in class_attrs:
|
|
189
|
+
cls.__length_hint__ = __wrapper_length_hint__
|
|
190
|
+
elif getattr(cls, "__length_hint__", None) is __wrapper_length_hint__:
|
|
191
|
+
delattr(cls, "__length_hint__")
|
|
192
|
+
|
|
193
|
+
if hasattr(self.__wrapped__, "__await__"):
|
|
194
|
+
if "__await__" not in class_attrs:
|
|
195
|
+
cls.__await__ = __wrapper_await__
|
|
196
|
+
elif getattr(cls, "__await__", None) is __wrapper_await__:
|
|
197
|
+
delattr(cls, "__await__")
|
|
198
|
+
|
|
199
|
+
if hasattr(self.__wrapped__, "__get__"):
|
|
200
|
+
if "__get__" not in class_attrs:
|
|
201
|
+
cls.__get__ = __wrapper_get__
|
|
202
|
+
elif getattr(cls, "__get__", None) is __wrapper_get__:
|
|
203
|
+
delattr(cls, "__get__")
|
|
204
|
+
|
|
205
|
+
if hasattr(self.__wrapped__, "__set__"):
|
|
206
|
+
if "__set__" not in class_attrs:
|
|
207
|
+
cls.__set__ = __wrapper_set__
|
|
208
|
+
elif getattr(cls, "__set__", None) is __wrapper_set__:
|
|
209
|
+
delattr(cls, "__set__")
|
|
210
|
+
|
|
211
|
+
if hasattr(self.__wrapped__, "__delete__"):
|
|
212
|
+
if "__delete__" not in class_attrs:
|
|
213
|
+
cls.__delete__ = __wrapper_delete__
|
|
214
|
+
elif getattr(cls, "__delete__", None) is __wrapper_delete__:
|
|
215
|
+
delattr(cls, "__delete__")
|
|
216
|
+
|
|
217
|
+
if hasattr(self.__wrapped__, "__set_name__"):
|
|
218
|
+
if "__set_name__" not in class_attrs:
|
|
219
|
+
cls.__set_name__ = __wrapper_set_name__
|
|
220
|
+
elif getattr(cls, "__set_name__", None) is __wrapper_set_name__:
|
|
221
|
+
delattr(cls, "__set_name__")
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
class LazyObjectProxy(AutoObjectProxy):
|
|
225
|
+
"""An object proxy which can generate/create the wrapped object on demand
|
|
226
|
+
when it is first needed.
|
|
227
|
+
"""
|
|
228
|
+
|
|
229
|
+
def __new__(cls, callback=None, *, interface=...):
|
|
230
|
+
"""Injects special dunder methods into a dynamically created subclass
|
|
231
|
+
as needed based on the wrapped object.
|
|
232
|
+
"""
|
|
233
|
+
|
|
234
|
+
if interface is ...:
|
|
235
|
+
interface = type(None)
|
|
236
|
+
|
|
237
|
+
namespace = {}
|
|
238
|
+
|
|
239
|
+
interface_attrs = dir(interface)
|
|
240
|
+
class_attrs = set(dir(cls))
|
|
241
|
+
|
|
242
|
+
if "__call__" in interface_attrs and "__call__" not in class_attrs:
|
|
243
|
+
namespace["__call__"] = __wrapper_call__
|
|
244
|
+
|
|
245
|
+
if "__iter__" in interface_attrs and "__iter__" not in class_attrs:
|
|
246
|
+
namespace["__iter__"] = __wrapper_iter__
|
|
247
|
+
|
|
248
|
+
if "__next__" in interface_attrs and "__next__" not in class_attrs:
|
|
249
|
+
namespace["__next__"] = __wrapper_next__
|
|
250
|
+
|
|
251
|
+
if "__aiter__" in interface_attrs and "__aiter__" not in class_attrs:
|
|
252
|
+
namespace["__aiter__"] = __wrapper_aiter__
|
|
253
|
+
|
|
254
|
+
if "__anext__" in interface_attrs and "__anext__" not in class_attrs:
|
|
255
|
+
namespace["__anext__"] = __wrapper_anext__
|
|
256
|
+
|
|
257
|
+
if (
|
|
258
|
+
"__length_hint__" in interface_attrs
|
|
259
|
+
and "__length_hint__" not in class_attrs
|
|
260
|
+
):
|
|
261
|
+
namespace["__length_hint__"] = __wrapper_length_hint__
|
|
262
|
+
|
|
263
|
+
# Note that not providing compatibility with generator-based coroutines
|
|
264
|
+
# (PEP 342) here as they are removed in Python 3.11+ and were deprecated
|
|
265
|
+
# in 3.8.
|
|
266
|
+
|
|
267
|
+
if "__await__" in interface_attrs and "__await__" not in class_attrs:
|
|
268
|
+
namespace["__await__"] = __wrapper_await__
|
|
269
|
+
|
|
270
|
+
if "__get__" in interface_attrs and "__get__" not in class_attrs:
|
|
271
|
+
namespace["__get__"] = __wrapper_get__
|
|
272
|
+
|
|
273
|
+
if "__set__" in interface_attrs and "__set__" not in class_attrs:
|
|
274
|
+
namespace["__set__"] = __wrapper_set__
|
|
275
|
+
|
|
276
|
+
if "__delete__" in interface_attrs and "__delete__" not in class_attrs:
|
|
277
|
+
namespace["__delete__"] = __wrapper_delete__
|
|
278
|
+
|
|
279
|
+
if "__set_name__" in interface_attrs and "__set_name__" not in class_attrs:
|
|
280
|
+
namespace["__set_name__"] = __wrapper_set_name__
|
|
281
|
+
|
|
282
|
+
name = cls.__name__
|
|
283
|
+
|
|
284
|
+
return super(AutoObjectProxy, cls).__new__(type(name, (cls,), namespace))
|
|
285
|
+
|
|
286
|
+
def __init__(self, callback=None, *, interface=...):
|
|
287
|
+
"""Initialize the object proxy with wrapped object as `None` but due
|
|
288
|
+
to presence of special `__wrapped_factory__` attribute addded first,
|
|
289
|
+
this will actually trigger the deferred creation of the wrapped object
|
|
290
|
+
when first needed.
|
|
291
|
+
"""
|
|
292
|
+
|
|
293
|
+
if callback is not None:
|
|
294
|
+
self.__wrapped_factory__ = callback
|
|
295
|
+
|
|
296
|
+
super().__init__(None)
|
|
297
|
+
|
|
298
|
+
__wrapped_initialized__ = False
|
|
299
|
+
|
|
300
|
+
def __wrapped_factory__(self):
|
|
301
|
+
return None
|
|
302
|
+
|
|
303
|
+
def __wrapped_get__(self):
|
|
304
|
+
"""Gets the wrapped object, creating it if necessary."""
|
|
305
|
+
|
|
306
|
+
# We synchronize on the class type, which will be unique to this instance
|
|
307
|
+
# since we inherit from `AutoObjectProxy` which creates a new class
|
|
308
|
+
# for each instance. If we synchronize on `self` or the method then
|
|
309
|
+
# we can end up in infinite recursion via `__getattr__()`.
|
|
310
|
+
|
|
311
|
+
with synchronized(type(self)):
|
|
312
|
+
# We were called because `__wrapped__` was not set, but because of
|
|
313
|
+
# multiple threads we may find that it has been set by the time
|
|
314
|
+
# we get the lock. So check again now whether `__wrapped__` is set.
|
|
315
|
+
# If it is then just return it, otherwise call the factory to
|
|
316
|
+
# create it.
|
|
317
|
+
|
|
318
|
+
if self.__wrapped_initialized__:
|
|
319
|
+
return self.__wrapped__
|
|
320
|
+
|
|
321
|
+
self.__wrapped__ = self.__wrapped_factory__()
|
|
322
|
+
|
|
323
|
+
self.__wrapped_initialized__ = True
|
|
324
|
+
|
|
325
|
+
return self.__wrapped__
|
|
326
|
+
|
|
327
|
+
|
|
328
|
+
def lazy_import(name, attribute=None, *, interface=...):
|
|
329
|
+
"""Lazily imports the module `name`, returning a `LazyObjectProxy` which
|
|
330
|
+
will import the module when it is first needed. When `name is a dotted name,
|
|
331
|
+
then the full dotted name is imported and the last module is taken as the
|
|
332
|
+
target. If `attribute` is provided then it is used to retrieve an attribute
|
|
333
|
+
from the module.
|
|
334
|
+
"""
|
|
335
|
+
|
|
336
|
+
if attribute is not None:
|
|
337
|
+
if interface is ...:
|
|
338
|
+
interface = Callable
|
|
339
|
+
else:
|
|
340
|
+
if interface is ...:
|
|
341
|
+
interface = ModuleType
|
|
342
|
+
|
|
343
|
+
def _import():
|
|
344
|
+
module = __import__(name, fromlist=[""])
|
|
345
|
+
|
|
346
|
+
if attribute is not None:
|
|
347
|
+
return getattr(module, attribute)
|
|
348
|
+
|
|
349
|
+
return module
|
|
350
|
+
|
|
351
|
+
return LazyObjectProxy(_import, interface=interface)
|
wrapt/weakrefs.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import functools
|
|
2
2
|
import weakref
|
|
3
3
|
|
|
4
|
-
from .__wrapt__ import
|
|
4
|
+
from .__wrapt__ import BaseObjectProxy, _FunctionWrapperBase
|
|
5
5
|
|
|
6
6
|
# A weak function proxy. This will work on instance methods, class
|
|
7
7
|
# methods, static methods and regular functions. Special treatment is
|
|
@@ -27,7 +27,7 @@ def _weak_function_proxy_callback(ref, proxy, callback):
|
|
|
27
27
|
callback(proxy)
|
|
28
28
|
|
|
29
29
|
|
|
30
|
-
class WeakFunctionProxy(
|
|
30
|
+
class WeakFunctionProxy(BaseObjectProxy):
|
|
31
31
|
"""A weak function proxy."""
|
|
32
32
|
|
|
33
33
|
__slots__ = ("_self_expired", "_self_instance")
|
wrapt/wrappers.py
CHANGED
|
@@ -87,7 +87,26 @@ class ObjectProxy(with_metaclass(_ObjectProxyMetaType)): # type: ignore[misc]
|
|
|
87
87
|
__slots__ = "__wrapped__"
|
|
88
88
|
|
|
89
89
|
def __init__(self, wrapped):
|
|
90
|
-
object.
|
|
90
|
+
"""Create an object proxy around the given object."""
|
|
91
|
+
|
|
92
|
+
if wrapped is None:
|
|
93
|
+
try:
|
|
94
|
+
callback = object.__getattribute__(self, "__wrapped_factory__")
|
|
95
|
+
except AttributeError:
|
|
96
|
+
callback = None
|
|
97
|
+
|
|
98
|
+
if callback is not None:
|
|
99
|
+
# If wrapped is none and class has a __wrapped_factory__
|
|
100
|
+
# method, then we don't set __wrapped__ yet and instead will
|
|
101
|
+
# defer creation of the wrapped object until it is first
|
|
102
|
+
# needed.
|
|
103
|
+
|
|
104
|
+
pass
|
|
105
|
+
|
|
106
|
+
else:
|
|
107
|
+
object.__setattr__(self, "__wrapped__", wrapped)
|
|
108
|
+
else:
|
|
109
|
+
object.__setattr__(self, "__wrapped__", wrapped)
|
|
91
110
|
|
|
92
111
|
# Python 3.2+ has the __qualname__ attribute, but it does not
|
|
93
112
|
# allow it to be overridden using a property and it must instead
|
|
@@ -106,6 +125,10 @@ class ObjectProxy(with_metaclass(_ObjectProxyMetaType)): # type: ignore[misc]
|
|
|
106
125
|
except AttributeError:
|
|
107
126
|
pass
|
|
108
127
|
|
|
128
|
+
@property
|
|
129
|
+
def __object_proxy__(self):
|
|
130
|
+
return ObjectProxy
|
|
131
|
+
|
|
109
132
|
def __self_setattr__(self, name, value):
|
|
110
133
|
object.__setattr__(self, name, value)
|
|
111
134
|
|
|
@@ -147,6 +170,10 @@ class ObjectProxy(with_metaclass(_ObjectProxyMetaType)): # type: ignore[misc]
|
|
|
147
170
|
return round(self.__wrapped__, ndigits)
|
|
148
171
|
|
|
149
172
|
def __mro_entries__(self, bases):
|
|
173
|
+
if not isinstance(self.__wrapped__, type) and hasattr(
|
|
174
|
+
self.__wrapped__, "__mro_entries__"
|
|
175
|
+
):
|
|
176
|
+
return self.__wrapped__.__mro_entries__(bases)
|
|
150
177
|
return (self.__wrapped__,)
|
|
151
178
|
|
|
152
179
|
def __lt__(self, other):
|
|
@@ -182,6 +209,7 @@ class ObjectProxy(with_metaclass(_ObjectProxyMetaType)): # type: ignore[misc]
|
|
|
182
209
|
|
|
183
210
|
elif name == "__wrapped__":
|
|
184
211
|
object.__setattr__(self, name, value)
|
|
212
|
+
|
|
185
213
|
try:
|
|
186
214
|
object.__delattr__(self, "__qualname__")
|
|
187
215
|
except AttributeError:
|
|
@@ -199,6 +227,13 @@ class ObjectProxy(with_metaclass(_ObjectProxyMetaType)): # type: ignore[misc]
|
|
|
199
227
|
except AttributeError:
|
|
200
228
|
pass
|
|
201
229
|
|
|
230
|
+
__wrapped_setattr_fixups__ = getattr(
|
|
231
|
+
self, "__wrapped_setattr_fixups__", None
|
|
232
|
+
)
|
|
233
|
+
|
|
234
|
+
if __wrapped_setattr_fixups__ is not None:
|
|
235
|
+
__wrapped_setattr_fixups__()
|
|
236
|
+
|
|
202
237
|
elif name == "__qualname__":
|
|
203
238
|
setattr(self.__wrapped__, name, value)
|
|
204
239
|
object.__setattr__(self, name, value)
|
|
@@ -214,11 +249,26 @@ class ObjectProxy(with_metaclass(_ObjectProxyMetaType)): # type: ignore[misc]
|
|
|
214
249
|
setattr(self.__wrapped__, name, value)
|
|
215
250
|
|
|
216
251
|
def __getattr__(self, name):
|
|
217
|
-
# If we
|
|
218
|
-
#
|
|
252
|
+
# If we need to lookup `__wrapped__` then the `__init__()` method
|
|
253
|
+
# cannot have been called, or this is a lazy object proxy which is
|
|
254
|
+
# deferring creation of the wrapped object until it is first needed.
|
|
219
255
|
|
|
220
256
|
if name == "__wrapped__":
|
|
221
|
-
|
|
257
|
+
# Note that we use existance of `__wrapped_factory__` to gate whether
|
|
258
|
+
# we can attempt to initialize the wrapped object lazily, but it is
|
|
259
|
+
# `__wrapped_get__` that we actually call to do the initialization.
|
|
260
|
+
# This is so that we can handle multithreading correctly by having
|
|
261
|
+
# `__wrapped_get__` use a lock to protect against multiple threads
|
|
262
|
+
# trying to initialize the wrapped object at the same time.
|
|
263
|
+
|
|
264
|
+
try:
|
|
265
|
+
object.__getattribute__(self, "__wrapped_factory__")
|
|
266
|
+
except AttributeError:
|
|
267
|
+
pass
|
|
268
|
+
else:
|
|
269
|
+
return object.__getattribute__(self, "__wrapped_get__")()
|
|
270
|
+
|
|
271
|
+
raise WrapperNotInitializedError("wrapper has not been initialized")
|
|
222
272
|
|
|
223
273
|
return getattr(self.__wrapped__, name)
|
|
224
274
|
|
|
@@ -227,7 +277,7 @@ class ObjectProxy(with_metaclass(_ObjectProxyMetaType)): # type: ignore[misc]
|
|
|
227
277
|
object.__delattr__(self, name)
|
|
228
278
|
|
|
229
279
|
elif name == "__wrapped__":
|
|
230
|
-
raise TypeError("__wrapped__
|
|
280
|
+
raise TypeError("__wrapped__ attribute cannot be deleted")
|
|
231
281
|
|
|
232
282
|
elif name == "__qualname__":
|
|
233
283
|
object.__delattr__(self, name)
|
|
@@ -318,52 +368,90 @@ class ObjectProxy(with_metaclass(_ObjectProxyMetaType)): # type: ignore[misc]
|
|
|
318
368
|
return other | self.__wrapped__
|
|
319
369
|
|
|
320
370
|
def __iadd__(self, other):
|
|
321
|
-
self.__wrapped__
|
|
322
|
-
|
|
371
|
+
if hasattr(self.__wrapped__, "__iadd__"):
|
|
372
|
+
self.__wrapped__ += other
|
|
373
|
+
return self
|
|
374
|
+
else:
|
|
375
|
+
return self.__object_proxy__(self.__wrapped__ + other)
|
|
323
376
|
|
|
324
377
|
def __isub__(self, other):
|
|
325
|
-
self.__wrapped__
|
|
326
|
-
|
|
378
|
+
if hasattr(self.__wrapped__, "__isub__"):
|
|
379
|
+
self.__wrapped__ -= other
|
|
380
|
+
return self
|
|
381
|
+
else:
|
|
382
|
+
return self.__object_proxy__(self.__wrapped__ - other)
|
|
327
383
|
|
|
328
384
|
def __imul__(self, other):
|
|
329
|
-
self.__wrapped__
|
|
330
|
-
|
|
385
|
+
if hasattr(self.__wrapped__, "__imul__"):
|
|
386
|
+
self.__wrapped__ *= other
|
|
387
|
+
return self
|
|
388
|
+
else:
|
|
389
|
+
return self.__object_proxy__(self.__wrapped__ * other)
|
|
331
390
|
|
|
332
391
|
def __itruediv__(self, other):
|
|
333
|
-
|
|
334
|
-
|
|
392
|
+
if hasattr(self.__wrapped__, "__itruediv__"):
|
|
393
|
+
self.__wrapped__ /= other
|
|
394
|
+
return self
|
|
395
|
+
else:
|
|
396
|
+
return self.__object_proxy__(self.__wrapped__ / other)
|
|
335
397
|
|
|
336
398
|
def __ifloordiv__(self, other):
|
|
337
|
-
self.__wrapped__
|
|
338
|
-
|
|
399
|
+
if hasattr(self.__wrapped__, "__ifloordiv__"):
|
|
400
|
+
self.__wrapped__ //= other
|
|
401
|
+
return self
|
|
402
|
+
else:
|
|
403
|
+
return self.__object_proxy__(self.__wrapped__ // other)
|
|
339
404
|
|
|
340
405
|
def __imod__(self, other):
|
|
341
|
-
self.__wrapped__
|
|
406
|
+
if hasattr(self.__wrapped__, "__imod__"):
|
|
407
|
+
self.__wrapped__ %= other
|
|
408
|
+
return self
|
|
409
|
+
else:
|
|
410
|
+
return self.__object_proxy__(self.__wrapped__ % other)
|
|
411
|
+
|
|
342
412
|
return self
|
|
343
413
|
|
|
344
414
|
def __ipow__(self, other): # type: ignore[misc]
|
|
345
|
-
self.__wrapped__
|
|
346
|
-
|
|
415
|
+
if hasattr(self.__wrapped__, "__ipow__"):
|
|
416
|
+
self.__wrapped__ **= other
|
|
417
|
+
return self
|
|
418
|
+
else:
|
|
419
|
+
return self.__object_proxy__(self.__wrapped__**other)
|
|
347
420
|
|
|
348
421
|
def __ilshift__(self, other):
|
|
349
|
-
self.__wrapped__
|
|
350
|
-
|
|
422
|
+
if hasattr(self.__wrapped__, "__ilshift__"):
|
|
423
|
+
self.__wrapped__ <<= other
|
|
424
|
+
return self
|
|
425
|
+
else:
|
|
426
|
+
return self.__object_proxy__(self.__wrapped__ << other)
|
|
351
427
|
|
|
352
428
|
def __irshift__(self, other):
|
|
353
|
-
self.__wrapped__
|
|
354
|
-
|
|
429
|
+
if hasattr(self.__wrapped__, "__irshift__"):
|
|
430
|
+
self.__wrapped__ >>= other
|
|
431
|
+
return self
|
|
432
|
+
else:
|
|
433
|
+
return self.__object_proxy__(self.__wrapped__ >> other)
|
|
355
434
|
|
|
356
435
|
def __iand__(self, other):
|
|
357
|
-
self.__wrapped__
|
|
358
|
-
|
|
436
|
+
if hasattr(self.__wrapped__, "__iand__"):
|
|
437
|
+
self.__wrapped__ &= other
|
|
438
|
+
return self
|
|
439
|
+
else:
|
|
440
|
+
return self.__object_proxy__(self.__wrapped__ & other)
|
|
359
441
|
|
|
360
442
|
def __ixor__(self, other):
|
|
361
|
-
self.__wrapped__
|
|
362
|
-
|
|
443
|
+
if hasattr(self.__wrapped__, "__ixor__"):
|
|
444
|
+
self.__wrapped__ ^= other
|
|
445
|
+
return self
|
|
446
|
+
else:
|
|
447
|
+
return self.__object_proxy__(self.__wrapped__ ^ other)
|
|
363
448
|
|
|
364
449
|
def __ior__(self, other):
|
|
365
|
-
self.__wrapped__
|
|
366
|
-
|
|
450
|
+
if hasattr(self.__wrapped__, "__ior__"):
|
|
451
|
+
self.__wrapped__ |= other
|
|
452
|
+
return self
|
|
453
|
+
else:
|
|
454
|
+
return self.__object_proxy__(self.__wrapped__ | other)
|
|
367
455
|
|
|
368
456
|
def __neg__(self):
|
|
369
457
|
return -self.__wrapped__
|
|
@@ -395,6 +483,19 @@ class ObjectProxy(with_metaclass(_ObjectProxyMetaType)): # type: ignore[misc]
|
|
|
395
483
|
def __index__(self):
|
|
396
484
|
return operator.index(self.__wrapped__)
|
|
397
485
|
|
|
486
|
+
def __matmul__(self, other):
|
|
487
|
+
return self.__wrapped__ @ other
|
|
488
|
+
|
|
489
|
+
def __rmatmul__(self, other):
|
|
490
|
+
return other @ self.__wrapped__
|
|
491
|
+
|
|
492
|
+
def __imatmul__(self, other):
|
|
493
|
+
if hasattr(self.__wrapped__, "__imatmul__"):
|
|
494
|
+
self.__wrapped__ @= other
|
|
495
|
+
return self
|
|
496
|
+
else:
|
|
497
|
+
return self.__object_proxy__(self.__wrapped__ @ other)
|
|
498
|
+
|
|
398
499
|
def __len__(self):
|
|
399
500
|
return len(self.__wrapped__)
|
|
400
501
|
|
|
@@ -425,8 +526,11 @@ class ObjectProxy(with_metaclass(_ObjectProxyMetaType)): # type: ignore[misc]
|
|
|
425
526
|
def __exit__(self, *args, **kwargs):
|
|
426
527
|
return self.__wrapped__.__exit__(*args, **kwargs)
|
|
427
528
|
|
|
428
|
-
def
|
|
429
|
-
return
|
|
529
|
+
def __aenter__(self):
|
|
530
|
+
return self.__wrapped__.__aenter__()
|
|
531
|
+
|
|
532
|
+
def __aexit__(self, *args, **kwargs):
|
|
533
|
+
return self.__wrapped__.__aexit__(*args, **kwargs)
|
|
430
534
|
|
|
431
535
|
def __copy__(self):
|
|
432
536
|
raise NotImplementedError("object proxy must define __copy__()")
|