zope.proxy 7.2__cp313-cp313-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.
zope/proxy/__init__.py ADDED
@@ -0,0 +1,523 @@
1
+ ##############################################################################
2
+ #
3
+ # Copyright (c) 2003 Zope Foundation and Contributors.
4
+ # All Rights Reserved.
5
+ #
6
+ # This software is subject to the provisions of the Zope Public License,
7
+ # Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
8
+ # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
9
+ # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
10
+ # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
11
+ # FOR A PARTICULAR PURPOSE.
12
+ #
13
+ ##############################################################################
14
+ """More convenience functions for dealing with proxies.
15
+ """
16
+ import operator
17
+ import os
18
+ import pickle
19
+
20
+ from zope.interface import moduleProvides
21
+
22
+ from zope.proxy.interfaces import IProxyIntrospection
23
+
24
+
25
+ moduleProvides(IProxyIntrospection)
26
+ __all__ = tuple(IProxyIntrospection)
27
+
28
+
29
+ def ProxyIterator(p):
30
+ yield p
31
+ while isProxy(p):
32
+ p = getProxiedObject(p)
33
+ yield p
34
+
35
+
36
+ _MARKER = object()
37
+
38
+
39
+ def _WrapperType_Lookup(type_, name):
40
+ """
41
+ Looks up information in class dictionaries in MRO
42
+ order, ignoring the proxy type itself.
43
+
44
+ Returns the first found object, or _MARKER
45
+ """
46
+
47
+ for base in type_.mro():
48
+ if base is AbstractPyProxyBase:
49
+ continue
50
+ res = base.__dict__.get(name, _MARKER)
51
+ if res is not _MARKER:
52
+ return res
53
+ return _MARKER
54
+
55
+
56
+ def _get_wrapped(self):
57
+ """
58
+ Helper method to access the wrapped object.
59
+ """
60
+ return super(AbstractPyProxyBase, self).__getattribute__('_wrapped')
61
+
62
+
63
+ class _EmptyInterfaceDescriptor:
64
+ """A descriptor for the attributes used on the class by the
65
+ Python implementation of `zope.interface`.
66
+
67
+ When wrapping builtin types, these descriptors prevent the objects
68
+ we find in the AbstractPyProxyBase from being used.
69
+ """
70
+
71
+ def __get__(self, inst, klass):
72
+ raise AttributeError()
73
+
74
+ def __set__(self, inst, value):
75
+ raise TypeError()
76
+
77
+ def __delete__(self, inst):
78
+ pass
79
+
80
+ def __iter__(self):
81
+ return self
82
+
83
+ def __next__(self):
84
+ raise StopIteration()
85
+ next = __next__
86
+
87
+
88
+ class _ProxyMetaclass(type):
89
+ # The metaclass is applied after the class definition
90
+ # for Py2/Py3 compatibility.
91
+ __implemented__ = _EmptyInterfaceDescriptor()
92
+
93
+
94
+ class AbstractPyProxyBase:
95
+ """
96
+ A reference implementation that cannot be instantiated. Most users
97
+ will want to use :class:`PyProxyBase`.
98
+
99
+ This type is intended to be used in multiple-inheritance
100
+ scenarios, where another super class already has defined
101
+ ``__slots__``. In order to subclass both that class and this
102
+ class, you must include the ``_wrapped`` value in your own
103
+ ``__slots__`` definition (or else you will get the infamous
104
+ TypeError: "multiple bases have instance lay-out conflicts")
105
+ """
106
+ __slots__ = ()
107
+
108
+ def __new__(cls, value=None):
109
+ # Some subclasses (zope.security.proxy) fail to pass the object
110
+ inst = super(AbstractPyProxyBase, cls).__new__(cls)
111
+ inst._wrapped = value
112
+ return inst
113
+
114
+ def __init__(self, obj):
115
+ self._wrapped = obj
116
+
117
+ def __call__(self, *args, **kw):
118
+ return self._wrapped(*args, **kw)
119
+
120
+ def __repr__(self):
121
+ return repr(self._wrapped)
122
+
123
+ def __str__(self):
124
+ return str(self._wrapped)
125
+
126
+ def __reduce__(self): # pragma: no cover (__reduce_ex__ prevents normal)
127
+ raise pickle.PicklingError
128
+
129
+ def __reduce_ex__(self, proto):
130
+ raise pickle.PicklingError
131
+
132
+ # Rich comparison protocol
133
+ def __lt__(self, other):
134
+ return self._wrapped < other
135
+
136
+ def __le__(self, other):
137
+ return self._wrapped <= other
138
+
139
+ def __eq__(self, other):
140
+ return self._wrapped == other
141
+
142
+ def __ne__(self, other):
143
+ return self._wrapped != other
144
+
145
+ def __gt__(self, other):
146
+ return self._wrapped > other
147
+
148
+ def __ge__(self, other):
149
+ return self._wrapped >= other
150
+
151
+ def __bool__(self):
152
+ return bool(self._wrapped)
153
+
154
+ def __hash__(self):
155
+ return hash(self._wrapped)
156
+
157
+ # Attribute protocol
158
+ def __getattribute__(self, name):
159
+ # Try to avoid accessing the _wrapped value until we need to.
160
+ # We don't know how subclasses may be storing it
161
+ # (e.g., persistent subclasses)
162
+ if name == '_wrapped':
163
+ return _get_wrapped(self)
164
+
165
+ if name in ('__class__', '__module__'):
166
+ # __class__ and __module__ are special cased in the C
167
+ # implementation, because we will always find them on the
168
+ # type of this object if we are being subclassed
169
+ return getattr(_get_wrapped(self), name)
170
+
171
+ if name in ('__reduce__', '__reduce_ex__'):
172
+ # These things we specifically override and no one
173
+ # can stop us, not even a subclass
174
+ return object.__getattribute__(self, name)
175
+
176
+ # First, look for descriptors in this object's type
177
+ type_self = type(self)
178
+ descriptor = _WrapperType_Lookup(type_self, name)
179
+ if descriptor is _MARKER:
180
+ # Nothing in the class, go straight to the wrapped object
181
+ return getattr(_get_wrapped(self), name)
182
+
183
+ if hasattr(descriptor, '__get__'):
184
+ if not hasattr(descriptor, '__set__'):
185
+ # Non-data-descriptor: call through to the wrapped object
186
+ # to see if it's there
187
+ try:
188
+ return getattr(_get_wrapped(self), name)
189
+ except AttributeError:
190
+ pass
191
+ # Data-descriptor on this type. Call it
192
+ return descriptor.__get__(self, type_self)
193
+ return descriptor
194
+
195
+ def __getattr__(self, name):
196
+ return getattr(self._wrapped, name)
197
+
198
+ def __setattr__(self, name, value):
199
+ if name == '_wrapped':
200
+ return super(AbstractPyProxyBase, self).__setattr__(name, value)
201
+
202
+ # First, look for descriptors in this object's type
203
+ type_self = type(self)
204
+ descriptor = _WrapperType_Lookup(type_self, name)
205
+ if descriptor is _MARKER or not hasattr(descriptor, '__set__'):
206
+ # Nothing in the class that's a descriptor,
207
+ # go straight to the wrapped object
208
+ return setattr(self._wrapped, name, value)
209
+
210
+ return object.__setattr__(self, name, value)
211
+
212
+ def __delattr__(self, name):
213
+ if name == '_wrapped':
214
+ raise AttributeError()
215
+ delattr(self._wrapped, name)
216
+
217
+ # Container protocols
218
+
219
+ def __len__(self):
220
+ return len(self._wrapped)
221
+
222
+ def __getitem__(self, key):
223
+ return self._wrapped[key]
224
+
225
+ def __setitem__(self, key, value):
226
+ self._wrapped[key] = value
227
+
228
+ def __delitem__(self, key):
229
+ del self._wrapped[key]
230
+
231
+ def __iter__(self):
232
+ # This handles a custom __iter__ and generator support at the same
233
+ # time.
234
+ return iter(self._wrapped)
235
+
236
+ def next(self):
237
+ # Called when we wrap an iterator itself.
238
+ return next(self._wrapped)
239
+
240
+ def __next__(self):
241
+ return self._wrapped.__next__()
242
+
243
+ # Python 2.7 won't let the C wrapper support __reversed__
244
+ # Uncomment this when the supported Python versions do
245
+ # def __reversed__(self):
246
+ # return reversed(self._wrapped)
247
+
248
+ def __contains__(self, item):
249
+ return item in self._wrapped
250
+
251
+ # Numeric protocol: unary operators
252
+ def __neg__(self):
253
+ return -self._wrapped
254
+
255
+ def __pos__(self):
256
+ return +self._wrapped
257
+
258
+ def __abs__(self):
259
+ return abs(self._wrapped)
260
+
261
+ def __invert__(self):
262
+ return ~self._wrapped
263
+
264
+ # Numeric protocol: unary conversions
265
+ def __complex__(self):
266
+ return complex(self._wrapped)
267
+
268
+ def __int__(self):
269
+ return int(self._wrapped)
270
+
271
+ def __float__(self):
272
+ return float(self._wrapped)
273
+
274
+ def __index__(self):
275
+ return operator.index(self._wrapped)
276
+
277
+ # Numeric protocol: binary arithmetic operators
278
+ def __add__(self, other):
279
+ return self._wrapped + other
280
+
281
+ def __sub__(self, other):
282
+ return self._wrapped - other
283
+
284
+ def __mul__(self, other):
285
+ return self._wrapped * other
286
+
287
+ def __floordiv__(self, other):
288
+ return self._wrapped // other
289
+
290
+ def __truediv__(self, other):
291
+ return self._wrapped / other
292
+
293
+ def __mod__(self, other):
294
+ return self._wrapped % other
295
+
296
+ def __divmod__(self, other):
297
+ return divmod(self._wrapped, other)
298
+
299
+ def __pow__(self, other, modulus=None):
300
+ if modulus is None:
301
+ return pow(self._wrapped, other)
302
+ return pow(self._wrapped, other, modulus)
303
+
304
+ def __radd__(self, other):
305
+ return other + self._wrapped
306
+
307
+ def __rsub__(self, other):
308
+ return other - self._wrapped
309
+
310
+ def __rmul__(self, other):
311
+ return other * self._wrapped
312
+
313
+ def __rfloordiv__(self, other):
314
+ return other // self._wrapped
315
+
316
+ def __rtruediv__(self, other):
317
+ return other / self._wrapped
318
+
319
+ def __rmod__(self, other):
320
+ return other % self._wrapped
321
+
322
+ def __rdivmod__(self, other):
323
+ return divmod(other, self._wrapped)
324
+
325
+ def __rpow__(self, other, modulus=None):
326
+ if modulus is None:
327
+ return pow(other, self._wrapped)
328
+ # We can't actually get here, because we can't lie about our type()
329
+ return pow(other, self._wrapped, modulus) # pragma: no cover
330
+
331
+ # Numeric protocol: binary bitwise operators
332
+ def __lshift__(self, other):
333
+ return self._wrapped << other
334
+
335
+ def __rshift__(self, other):
336
+ return self._wrapped >> other
337
+
338
+ def __and__(self, other):
339
+ return self._wrapped & other
340
+
341
+ def __xor__(self, other):
342
+ return self._wrapped ^ other
343
+
344
+ def __or__(self, other):
345
+ return self._wrapped | other
346
+
347
+ def __rlshift__(self, other):
348
+ return other << self._wrapped
349
+
350
+ def __rrshift__(self, other):
351
+ return other >> self._wrapped
352
+
353
+ def __rand__(self, other):
354
+ return other & self._wrapped
355
+
356
+ def __rxor__(self, other):
357
+ return other ^ self._wrapped
358
+
359
+ def __ror__(self, other):
360
+ return other | self._wrapped
361
+
362
+ # Numeric protocol: binary in-place operators
363
+ def __iadd__(self, other):
364
+ self._wrapped += other
365
+ return self
366
+
367
+ def __isub__(self, other):
368
+ self._wrapped -= other
369
+ return self
370
+
371
+ def __imul__(self, other):
372
+ self._wrapped *= other
373
+ return self
374
+
375
+ def __itruediv__(self, other):
376
+ self._wrapped /= other
377
+ return self
378
+
379
+ def __ifloordiv__(self, other):
380
+ self._wrapped //= other
381
+ return self
382
+
383
+ def __imod__(self, other):
384
+ self._wrapped %= other
385
+ return self
386
+
387
+ def __ilshift__(self, other):
388
+ self._wrapped <<= other
389
+ return self
390
+
391
+ def __irshift__(self, other):
392
+ self._wrapped >>= other
393
+ return self
394
+
395
+ def __iand__(self, other):
396
+ self._wrapped &= other
397
+ return self
398
+
399
+ def __ixor__(self, other):
400
+ self._wrapped ^= other
401
+ return self
402
+
403
+ def __ior__(self, other):
404
+ self._wrapped |= other
405
+ return self
406
+
407
+ def __ipow__(self, other, modulus=None):
408
+ if modulus is None:
409
+ self._wrapped **= other
410
+ else: # pragma: no cover
411
+ # There is no syntax which triggers in-place pow w/ modulus
412
+ self._wrapped = pow(self._wrapped, other, modulus)
413
+ return self
414
+
415
+
416
+ AbstractPyProxyBase = _ProxyMetaclass('AbstractPyProxyBase', (),
417
+ dict(AbstractPyProxyBase.__dict__))
418
+
419
+
420
+ class PyProxyBase(AbstractPyProxyBase):
421
+ """Reference implementation.
422
+ """
423
+ __slots__ = ('_wrapped', )
424
+
425
+
426
+ def py_getProxiedObject(obj):
427
+ if isinstance(obj, PyProxyBase):
428
+ return obj._wrapped
429
+ return obj
430
+
431
+
432
+ def py_setProxiedObject(obj, new_value):
433
+ if not isinstance(obj, PyProxyBase):
434
+ raise TypeError('Not a proxy')
435
+ old, obj._wrapped = obj._wrapped, new_value
436
+ return old
437
+
438
+
439
+ def py_isProxy(obj, klass=None):
440
+ if klass is None:
441
+ klass = PyProxyBase
442
+ return isinstance(obj, klass)
443
+
444
+
445
+ def py_sameProxiedObjects(lhs, rhs):
446
+ while isinstance(lhs, PyProxyBase):
447
+ lhs = super(PyProxyBase, lhs).__getattribute__('_wrapped')
448
+ while isinstance(rhs, PyProxyBase):
449
+ rhs = super(PyProxyBase, rhs).__getattribute__('_wrapped')
450
+ return lhs is rhs
451
+
452
+
453
+ def py_queryProxy(obj, klass=None, default=None):
454
+ if klass is None:
455
+ klass = PyProxyBase
456
+ while obj is not None and not isinstance(obj, klass):
457
+ obj = getattr(obj, '_wrapped', None)
458
+ if obj is not None:
459
+ return obj
460
+ return default
461
+
462
+
463
+ def py_queryInnerProxy(obj, klass=None, default=None):
464
+ if klass is None:
465
+ klass = PyProxyBase
466
+ found = []
467
+ while obj is not None:
468
+ if isinstance(obj, klass):
469
+ found.append(obj) # stack
470
+ obj = getattr(obj, '_wrapped', None)
471
+ if found:
472
+ return found[-1]
473
+ return default
474
+
475
+
476
+ def py_removeAllProxies(obj):
477
+ while isinstance(obj, PyProxyBase):
478
+ obj = super(PyProxyBase, obj).__getattribute__('_wrapped')
479
+ return obj
480
+
481
+
482
+ _c_available = False
483
+ if not int(os.environ.get('PURE_PYTHON', '0')):
484
+ try: # pragma: no cover
485
+ from zope.proxy._zope_proxy_proxy import ProxyBase as _c_available
486
+ except ImportError:
487
+ pass
488
+
489
+
490
+ class PyNonOverridable:
491
+ "Deprecated, only for BWC."
492
+
493
+ def __init__(self, method_desc): # pragma: no cover PyPy
494
+ self.desc = method_desc
495
+
496
+
497
+ if _c_available: # pragma: no cover
498
+ # Python API: not used in this module
499
+ # API for proxy-using C extensions.
500
+ from zope.proxy._zope_proxy_proxy import _CAPI # noqa: F401 unused
501
+ from zope.proxy._zope_proxy_proxy import ProxyBase
502
+ from zope.proxy._zope_proxy_proxy import getProxiedObject
503
+ from zope.proxy._zope_proxy_proxy import isProxy
504
+ from zope.proxy._zope_proxy_proxy import queryInnerProxy
505
+ from zope.proxy._zope_proxy_proxy import queryProxy
506
+ from zope.proxy._zope_proxy_proxy import removeAllProxies
507
+ from zope.proxy._zope_proxy_proxy import sameProxiedObjects
508
+ from zope.proxy._zope_proxy_proxy import setProxiedObject
509
+
510
+ else:
511
+ # no C extension available, fall back
512
+ ProxyBase = PyProxyBase
513
+ getProxiedObject = py_getProxiedObject
514
+ setProxiedObject = py_setProxiedObject
515
+ isProxy = py_isProxy
516
+ sameProxiedObjects = py_sameProxiedObjects
517
+ queryProxy = py_queryProxy
518
+ queryInnerProxy = py_queryInnerProxy
519
+ removeAllProxies = py_removeAllProxies
520
+
521
+
522
+ def non_overridable(func):
523
+ return property(lambda self: func.__get__(self))