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