• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

zopefoundation / zope.proxy / 16098813542

18 Feb 2025 08:01AM UTC coverage: 99.941% (+0.002%) from 99.939%
16098813542

push

github

web-flow
Update Python version support. (#74)

* Drop support for Python 3.8.
* Add preliminary support for Python 3.14.

---------

Co-authored-by: Jens Vagelpohl <jens@plyp.com>

213 of 213 branches covered (100.0%)

Branch coverage included in aggregate %.

1481 of 1482 relevant lines covered (99.93%)

6.99 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

100.0
/src/zope/proxy/tests/test_proxy.py
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
"""Test base proxy class.
7✔
15
"""
16
import pickle
7✔
17
import unittest
7✔
18

19
from .. import _c_available
7✔
20

21

22
try:
7✔
23
    import zope.security
7✔
24
except ModuleNotFoundError:  # pragma: no cover
25
    _HAVE_ZOPE_SECURITY = False
26
else:
27
    _HAVE_ZOPE_SECURITY = True
7✔
28
    del zope.security
7✔
29

30

31
class ModuleConformanceCase(unittest.TestCase):
7✔
32

33
    def test_module_conforms_to_IProxyIntrospection(self):
7✔
34
        from zope.interface.verify import verifyObject
7✔
35

36
        import zope.proxy
7✔
37
        from zope.proxy.interfaces import IProxyIntrospection
7✔
38
        verifyObject(IProxyIntrospection, zope.proxy)
7✔
39

40

41
class PyProxyBaseTestCase(unittest.TestCase):
7✔
42

43
    # Names of special methods
44
    getslice = '__getitem__'
7✔
45
    setslice = '__setitem__'
7✔
46

47
    def _getTargetClass(self):
7✔
48
        from zope.proxy import PyProxyBase
7✔
49
        return PyProxyBase
7✔
50

51
    def _makeOne(self, o):
7✔
52
        return self._getTargetClass()(o)
7✔
53

54
    def test_constructor(self):
7✔
55
        o = object()
7✔
56
        self.assertRaises(TypeError, self._makeOne, o, o)
7✔
57
        self.assertRaises(TypeError, self._makeOne, o, key='value')
7✔
58
        self.assertRaises(TypeError, self._makeOne, key='value')
7✔
59

60
    def test_subclass_constructor(self):
7✔
61
        class MyProxy(self._getTargetClass()):
7✔
62
            def __new__(cls, *args, **kwds):
7✔
63
                return super().__new__(cls, *args, **kwds)
7✔
64

65
            def __init__(self, *args, **kwds):
7✔
66
                super().__init__(*args, **kwds)
7✔
67
        o1 = object()
7✔
68
        o2 = object()
7✔
69
        o = MyProxy((o1, o2))
7✔
70

71
        self.assertEqual(o1, o[0])
7✔
72
        self.assertEqual(o2, o[1])
7✔
73

74
        self.assertRaises(TypeError, MyProxy, o1, o2)
7✔
75
        self.assertRaises(TypeError, MyProxy, o1, key='value')
7✔
76
        self.assertRaises(TypeError, MyProxy, key='value')
7✔
77

78
        # Check that are passed to __init__() overrides what's passed
79
        # to __new__().
80
        class MyProxy2(self._getTargetClass()):
7✔
81
            def __new__(cls, *args, **kwds):
7✔
82
                return super().__new__(cls, 'value')
7✔
83

84
        proxy = MyProxy2('splat!')
7✔
85
        self.assertEqual(list(proxy), list('splat!'))
7✔
86

87
        class MyProxy3(MyProxy2):
7✔
88
            def __init__(self, arg):
7✔
89
                if list(self) != list('value'):
7✔
90
                    raise AssertionError("list(self) != list('value')")
91
                super().__init__('another')
7✔
92

93
        proxy = MyProxy3('notused')
7✔
94
        self.assertEqual(list(proxy), list('another'))
7✔
95

96
    def test_custom_int_to_int(self):
7✔
97
        class CustomClass:
7✔
98
            def __int__(self):
7✔
99
                return 42
7✔
100
        proxy = self._makeOne(CustomClass())
7✔
101
        self.assertEqual(42, int(proxy))
7✔
102

103
    def test_string_to_float(self):
7✔
104
        proxy = self._makeOne("14")
7✔
105
        self.assertEqual(float("14"), float(proxy))
7✔
106

107
    def test_incorrect_string_to_int(self):
7✔
108
        proxy = self._makeOne("")
7✔
109
        self.assertRaises(ValueError, int, proxy)
7✔
110

111
    def test_incorrect_string_to_float(self):
7✔
112
        proxy = self._makeOne("")
7✔
113
        self.assertRaises(ValueError, float, proxy)
7✔
114

115
    def test_custom_float_to_float(self):
7✔
116
        class CustomClass:
7✔
117
            def __float__(self):
7✔
118
                return 42.0
7✔
119
        proxy = self._makeOne(CustomClass())
7✔
120
        self.assertEqual(42.0, float(proxy))
7✔
121

122
    def test___call__(self):
7✔
123
        def _foo():
7✔
124
            return 'FOO'
7✔
125
        proxy = self._makeOne(_foo)
7✔
126
        self.assertEqual(proxy(), 'FOO')
7✔
127

128
    def test___repr__(self):
7✔
129
        def _foo():
7✔
130
            raise AssertionError("Not called")
131
        proxy = self._makeOne(_foo)
7✔
132
        self.assertEqual(repr(proxy), repr(_foo))
7✔
133

134
    def test___str__(self):
7✔
135
        def _foo():
7✔
136
            raise AssertionError("Not called")
137
        proxy = self._makeOne(_foo)
7✔
138
        self.assertEqual(str(proxy), str(_foo))
7✔
139

140
    def test__reduce__raises(self):
7✔
141
        proxy = self._makeOne('foo')
7✔
142

143
        with self.assertRaises(pickle.PicklingError):
7✔
144
            proxy.__reduce__()
7✔
145

146
    def test__reduce_ex__raises(self):
7✔
147
        proxy = self._makeOne('foo')
7✔
148

149
        with self.assertRaises(pickle.PicklingError):
7✔
150
            proxy.__reduce_ex__(0)
7✔
151

152
    def test___eq___and___ne__(self):
7✔
153
        w = self._makeOne('foo')
7✔
154
        self.assertEqual(w, 'foo')
7✔
155

156
        o1 = Comparable(1)
7✔
157
        o2 = Comparable(1.0)
7✔
158
        o3 = Comparable("splat!")
7✔
159

160
        w1 = self._makeOne(o1)
7✔
161
        w2 = self._makeOne(o2)
7✔
162
        w3 = self._makeOne(o3)
7✔
163

164
        self.assertEqual(o1, w1)
7✔
165
        self.assertEqual(o1, w2)
7✔
166
        self.assertEqual(o2, w1)
7✔
167
        self.assertEqual(w1, o2)
7✔
168
        self.assertEqual(w2, o1)
7✔
169

170
        self.assertNotEqual(o3, w1)
7✔
171
        self.assertNotEqual(w1, o3)
7✔
172
        self.assertNotEqual(w3, o1)
7✔
173
        self.assertNotEqual(o1, w3)
7✔
174

175
    def test___lt___and___le__(self):
7✔
176
        o1 = Comparable(1)
7✔
177
        o2 = Comparable(2.0)
7✔
178

179
        w1 = self._makeOne(o1)
7✔
180
        w2 = self._makeOne(o2)
7✔
181

182
        self.assertLess(w1, w2)
7✔
183
        self.assertLessEqual(w1, w2)
7✔
184
        self.assertLess(o1, w2)
7✔
185
        self.assertLessEqual(o1, w2)
7✔
186
        self.assertLess(w1, o2)
7✔
187
        self.assertLessEqual(w2, o2)
7✔
188

189
    def test___gt___and___ge__(self):
7✔
190
        o1 = Comparable(1)
7✔
191
        o2 = Comparable(2.0)
7✔
192

193
        w1 = self._makeOne(o1)
7✔
194
        w2 = self._makeOne(o2)
7✔
195

196
        self.assertGreater(w2, w1)
7✔
197
        self.assertGreaterEqual(w2, w1)
7✔
198
        self.assertGreater(w2, o1)
7✔
199
        self.assertGreaterEqual(w2, o1)
7✔
200
        self.assertGreater(o2, w1)
7✔
201
        self.assertGreaterEqual(o2, w2)
7✔
202

203
    def test___bool__(self):
7✔
204
        w = self._makeOne(None)
7✔
205
        self.assertFalse(w)
7✔
206
        self.assertTrue(not w)
7✔
207

208
    def test___hash__(self):
7✔
209
        w1 = self._makeOne(1)
7✔
210
        self.assertEqual(hash(w1), hash(1))
7✔
211

212
    def test___getattr__miss_both(self):
7✔
213
        class Foo:
7✔
214
            pass
7✔
215
        o = Foo()
7✔
216
        w = self._makeOne(o)
7✔
217

218
        def _try():
7✔
219
            return w.nonesuch
7✔
220
        self.assertRaises(AttributeError, _try)
7✔
221

222
    def test___getattr__delegates_to_wrapped(self):
7✔
223
        class Foo:
7✔
224
            pass
7✔
225
        o = Foo()
7✔
226
        o.foo = 1
7✔
227
        w = self._makeOne(o)
7✔
228
        self.assertEqual(w.foo, 1)
7✔
229

230
    def test___getattr__delegates_to_wrapped_when_conflict(self):
7✔
231
        class Proxy(self._getTargetClass()):
7✔
232
            def foo(self):
7✔
233
                raise AssertionError("Not called")
234

235
        class Foo:
7✔
236
            def foo(self):
7✔
237
                return 'FOO'
7✔
238
        o = Foo()
7✔
239
        w = Proxy(o)
7✔
240
        self.assertEqual(w.foo(), 'FOO')
7✔
241

242
    def test___setattr__delegates_to_wrapped(self):
7✔
243
        class Foo:
7✔
244
            pass
7✔
245
        o = Foo()
7✔
246
        w = self._makeOne(o)
7✔
247
        w.foo = 1
7✔
248
        self.assertEqual(o.foo, 1)
7✔
249

250
    def test___setattr__sets_proxy_property(self):
7✔
251
        class Proxy(self._getTargetClass()):
7✔
252
            bar = property(
7✔
253
                lambda s: s.__dict__.get('_bar'),
254
                lambda s, v: s.__dict__.__setitem__('_bar', v)
255
            )
256

257
        class Foo:
7✔
258
            pass
7✔
259
        o = Foo()
7✔
260
        w = Proxy(o)
7✔
261
        w.bar = 43
7✔
262
        self.assertEqual(w.bar, 43)
7✔
263
        self.assertRaises(AttributeError, getattr, o, 'bar')
7✔
264

265
    def test___delattr___wrapped(self):
7✔
266
        class Foo:
7✔
267
            pass
7✔
268
        o = Foo()
7✔
269
        o.foo = 1
7✔
270
        w = self._makeOne(o)
7✔
271

272
        def _try():
7✔
273
            del w._wrapped
7✔
274
        self.assertRaises(AttributeError, _try)
7✔
275

276
    def test___delattr__delegates_to_wrapped(self):
7✔
277
        class Foo:
7✔
278
            pass
7✔
279
        o = Foo()
7✔
280
        o.foo = 1
7✔
281
        w = self._makeOne(o)
7✔
282
        del w.foo
7✔
283
        self.assertNotIn('foo', o.__dict__)
7✔
284

285
    def test___len__(self):
7✔
286
        l_ = []
7✔
287
        w = self._makeOne(l_)
7✔
288
        self.assertEqual(len(w), 0)
7✔
289
        l_.append(0)
7✔
290
        self.assertEqual(len(w), 1)
7✔
291

292
    def test___getitem_____setitem_____delitem__(self):
7✔
293
        w = self._makeOne({})
7✔
294
        self.assertRaises(KeyError, lambda: w[1])
7✔
295
        w[1] = 'a'
7✔
296
        self.assertEqual(w[1], 'a')
7✔
297
        del w[1]
7✔
298
        self.assertRaises(KeyError, lambda: w[1])
7✔
299

300
        def del_w_1():
7✔
301
            del w[1]
7✔
302
        self.assertRaises(KeyError, del_w_1)
7✔
303

304
    def test___getitem__w_slice_against_list(self):
7✔
305
        # Lists have special slicing behavior.
306
        pList = self._makeOne([1, 2])
7✔
307
        self.assertEqual(pList[-1:], [2])
7✔
308
        self.assertEqual(pList[-2:], [1, 2])
7✔
309
        self.assertEqual(pList[-3:], [1, 2])
7✔
310

311
    def test___getitem__w_slice_against_tuple(self):
7✔
312
        # Tuples also have special slicing behavior.
313
        pTuple = self._makeOne((1, 2))
7✔
314
        self.assertEqual(pTuple[-1:], (2,))
7✔
315
        self.assertEqual(pTuple[-2:], (1, 2))
7✔
316
        self.assertEqual(pTuple[-3:], (1, 2))
7✔
317

318
    def test___getitem__w_slice_against_derived_list(self):
7✔
319
        data = [1, 2]
7✔
320

321
        class DerivedList(list):
7✔
322
            pass
7✔
323

324
        pList = self._makeOne(DerivedList(data))
7✔
325

326
        self.assertEqual(pList[-1:], data[-1:])
7✔
327
        self.assertEqual(pList[-2:], data[-2:])
7✔
328
        self.assertEqual(pList[-3:], data[-3:])
7✔
329

330
    def test___getitem__w_slice_against_class_w_custom___getslice__(self):
7✔
331
        import sys
7✔
332

333
        class Slicer:
7✔
334
            def __len__(self):
7✔
335
                return 2
7✔
336

337
            def __getitem__(self, a_slice):
7✔
338
                # We basically just return what the test expects.
339
                # Mostly that's the computed indices (yay!) but there are
340
                # a few special cases.
341
                indices = a_slice.indices(len(self))
7✔
342
                return (
7✔
343
                    indices[0] if a_slice.start != -3 else -1,
344
                    indices[-1] if a_slice.stop is not None else sys.maxsize)
345

346
        pSlicer = self._makeOne(Slicer())
7✔
347
        self.assertEqual(pSlicer[:1][0], 0)
7✔
348
        self.assertEqual(pSlicer[:1][1], 1)
7✔
349
        self.assertEqual(pSlicer[:-1][0], 0)
7✔
350
        self.assertEqual(pSlicer[:-1][1], 1)
7✔
351
        self.assertEqual(pSlicer[-1:][0], 1)
7✔
352
        self.assertEqual(pSlicer[-2:][0], 0)
7✔
353
        self.assertEqual(pSlicer[-3:], (-1, sys.maxsize))
7✔
354

355
    def test___getslice___dne_uses_getitem(self):
7✔
356
        class Missing(Exception):
7✔
357
            pass
7✔
358

359
        class Get:
7✔
360
            def __getitem__(self, x):
7✔
361
                raise Missing('__getitem__')
7✔
362

363
        target = Get()
7✔
364
        proxy = self._makeOne(target)
7✔
365
        with self.assertRaisesRegex(Missing, '__getitem__'):
7✔
366
            proxy[1:2]
7✔
367

368
    def test___getslice___error_propagates(self):
7✔
369

370
        class Missing(Exception):
7✔
371
            pass
7✔
372

373
        class Get:
7✔
374
            def __getitem__(self, x):
7✔
375
                raise Missing('__getitem__')
7✔
376

377
        target = Get()
7✔
378
        proxy = self._makeOne(target)
7✔
379
        with self.assertRaisesRegex(Missing, self.getslice):
7✔
380
            proxy[1:2]
7✔
381

382
    def test___setslice___against_list(self):
7✔
383
        # Lists have special slicing behavior for assignment as well.
384
        pList = self._makeOne([1, 2])
7✔
385
        pList[-1:] = [3, 4]
7✔
386
        self.assertEqual(pList, [1, 3, 4])
7✔
387
        pList = self._makeOne([1, 2])
7✔
388
        pList[-2:] = [3, 4]
7✔
389
        self.assertEqual(pList, [3, 4])
7✔
390
        pList = self._makeOne([1, 2])
7✔
391
        pList[-3:] = [3, 4]
7✔
392
        self.assertEqual(pList, [3, 4])
7✔
393

394
    def test___setslice___against_derived_list(self):
7✔
395
        # This behavior should be true for all list-derived classes.
396
        class DerivedList(list):
7✔
397
            pass
7✔
398

399
        pList = self._makeOne(DerivedList([1, 2]))
7✔
400
        pList[-1:] = [3, 4]
7✔
401
        self.assertEqual(pList, [1, 3, 4])
7✔
402
        pList = self._makeOne(DerivedList([1, 2]))
7✔
403
        pList[-2:] = [3, 4]
7✔
404
        self.assertEqual(pList, [3, 4])
7✔
405
        pList = self._makeOne(DerivedList([1, 2]))
7✔
406
        pList[-3:] = [3, 4]
7✔
407
        self.assertEqual(pList, [3, 4])
7✔
408

409
    def test___setslice___error_propagates(self):
7✔
410
        class Missing(Exception):
7✔
411
            pass
7✔
412

413
        class Set:
7✔
414
            def __setitem__(self, k, v):
7✔
415
                raise Missing('__setitem__')
7✔
416

417
        target = Set()
7✔
418
        proxy = self._makeOne(target)
7✔
419
        with self.assertRaisesRegex(Missing, self.setslice):
7✔
420
            proxy[1:2] = 1
7✔
421

422
    def test___setslice___dne_uses_setitem(self):
7✔
423
        class Missing(Exception):
7✔
424
            pass
7✔
425

426
        class Set:
7✔
427
            def __setitem__(self, k, v):
7✔
428
                raise Missing('__setitem__')
7✔
429

430
        target = Set()
7✔
431
        proxy = self._makeOne(target)
7✔
432
        with self.assertRaisesRegex(Missing, '__setitem__'):
7✔
433
            proxy[1:2] = 1
7✔
434

435
    def test___iter___w_wrapped_iterable(self):
7✔
436
        a = [1, 2, 3]
7✔
437
        b = []
7✔
438
        for x in self._makeOne(a):
7✔
439
            b.append(x)
7✔
440
        self.assertEqual(a, b)
7✔
441

442
    def test___iter___w_wrapped_iterator(self):
7✔
443
        # Wrap an iterator before starting iteration.
444
        # PyObject_GetIter() will still be called on the proxy.
445
        a = [1, 2, 3]
7✔
446
        b = []
7✔
447
        for x in self._makeOne(iter(a)):
7✔
448
            b.append(x)
7✔
449
        self.assertEqual(a, b)
7✔
450
        t = tuple(self._makeOne(iter(a)))
7✔
451
        self.assertEqual(t, (1, 2, 3))
7✔
452

453
    def test___iter___returns_self_if_defined(self):
7✔
454
        # Return the wrapped object itself, if it is an iterator.
455
        class MyIter:
7✔
456
            def __iter__(self):
7✔
457
                return self
7✔
458

459
            def __next__(self):
7✔
460
                raise AssertionError("Not called")
461
            next = __next__
7✔
462
        myIter = MyIter()
7✔
463
        p = self._makeOne(myIter)
7✔
464
        self.assertEqual(iter(p), p)
7✔
465
        self.assertIsInstance(iter(p), MyIter)
7✔
466

467
    def test___iter___next_when_returned_by_iterable(self):
7✔
468
        # Wrap an iterator within the iteration protocol, expecting it
469
        # still to work.  PyObject_GetIter() will not be called on the
470
        # proxy, so the tp_iter slot won't unwrap it.
471

472
        class Iterable:
7✔
473
            def __init__(self, test, data):
7✔
474
                self.test = test
7✔
475
                self.data = data
7✔
476

477
            def __iter__(self):
7✔
478
                return self.test._makeOne(iter(self.data))
7✔
479

480
        a = [1, 2, 3]
7✔
481
        b = []
7✔
482
        for x in Iterable(self, a):
7✔
483
            b.append(x)
7✔
484
        self.assertEqual(a, b)
7✔
485

486
    # Python 2.7 won't let the C wrapper support __reversed__ :(
487
    # def test___reversed__(self):
488
    #    w = self._makeOne([0, 1, 2, 3])
489
    #    self.assertEqual(list(reversed(w)), [3, 2, 1, 0])
490

491
    def test___contains__(self):
7✔
492
        w = self._makeOne([0, 1, 2, 3])
7✔
493
        self.assertIn(1, w)
7✔
494
        self.assertNotIn(4, w)
7✔
495

496
    def test___index__(self):
7✔
497
        import operator
7✔
498
        w = self._makeOne(42)
7✔
499
        self.assertEqual(operator.index(w), 42)
7✔
500

501
    # Numeric ops.
502

503
    @property
7✔
504
    def unops(self):
7✔
505
        ops = [
7✔
506
            "-x",
507
            "+x",
508
            "abs(x)",
509
            "~x",
510
            "int(x)",
511
            "float(x)",
512
            "complex(x)",
513
        ]
514
        return ops
7✔
515

516
    def test_unops(self):
7✔
517
        for expr in self.unops:
7✔
518
            x = 1
7✔
519
            y = eval(expr)
7✔
520
            x = self._makeOne(1)
7✔
521
            z = eval(expr)
7✔
522
            self.assertEqual(z, y, f'x={x!r}; expr={expr!r}')
7✔
523

524
    def test_odd_unops(self):
7✔
525
        # unops that don't return a proxy
526
        funcs = (lambda x: not x,)
7✔
527
        for func in funcs:
7✔
528
            self.assertEqual(func(self._makeOne(100)), func(100))
7✔
529

530
    binops = [
7✔
531
        "x+y", "x-y", "x*y", "x/y", "x//y", "x%y", "divmod(x, y)",
532
        "x**y",  # "pow(x,y,3)" (RHS coercion not supported w/ modulus)
533
        "x<<y", "x>>y", "x&y", "x|y", "x^y",
534
    ]
535

536
    def test_binops(self):
7✔
537
        for expr in self.binops:
7✔
538
            first = 1
7✔
539
            for x in [1, self._makeOne(1)]:
7✔
540
                for y in [2, self._makeOne(2)]:
7✔
541
                    if first:
7✔
542
                        z = eval(expr)
7✔
543
                        first = 0
7✔
544
                    else:
545
                        msg = f'x={x!r}; y={y!r}; expr={expr!r}'
7✔
546
                        self.assertEqual(eval(expr), z, msg)
7✔
547

548
    def test_pow_w_modulus(self):
7✔
549
        x = self._makeOne(2)
7✔
550
        # Can't coerce 2nd / 3rd args in pure Python, because we can't
551
        # lie about our type
552
        self.assertEqual(pow(x, 3, 3), 2)
7✔
553

554
    def test_inplace(self):
7✔
555
        # TODO: should test all inplace operators...
556
        pa = self._makeOne(1)
7✔
557
        pa += 2
7✔
558
        self.assertEqual(pa, 3)
7✔
559

560
        a = [1, 2, 3]
7✔
561
        pa = qa = self._makeOne(a)
7✔
562
        pa += [4, 5, 6]
7✔
563
        self.assertIs(pa, qa)
7✔
564
        self.assertEqual(a, [1, 2, 3, 4, 5, 6])
7✔
565

566
        pa = self._makeOne(2)
7✔
567
        pa -= 1
7✔
568
        self.assertEqual(pa, 1)
7✔
569
        pa *= 4
7✔
570
        self.assertEqual(pa, 4)
7✔
571
        pa /= 2
7✔
572
        self.assertEqual(pa, 2)
7✔
573
        pa //= 2
7✔
574
        self.assertEqual(pa, 1)
7✔
575
        pa += 2
7✔
576
        self.assertEqual(pa, 3)
7✔
577
        pa %= 2
7✔
578
        self.assertEqual(pa, 1)
7✔
579

580
        pa = self._makeOne(2)
7✔
581
        pa **= 2
7✔
582
        self.assertEqual(pa, 4)
7✔
583
        pa <<= 1
7✔
584
        self.assertEqual(pa, 8)
7✔
585
        pa >>= 2
7✔
586
        self.assertEqual(pa, 2)
7✔
587

588
        pa = self._makeOne(7)
7✔
589
        pa &= 6
7✔
590
        self.assertEqual(pa, 6)
7✔
591
        pa |= 16
7✔
592
        self.assertEqual(pa, 22)
7✔
593
        pa ^= 2
7✔
594
        self.assertEqual(pa, 20)
7✔
595

596
    def test___class__(self):
7✔
597
        o = object()
7✔
598
        w = self._makeOne(o)
7✔
599
        self.assertIs(w.__class__, o.__class__)
7✔
600

601
    def test_descriptor__set___only_in_proxy_subclass(self):
7✔
602

603
        class Descriptor:
7✔
604
            value = None
7✔
605
            instance = None
7✔
606

607
            def __set__(self, instance, value):
7✔
608
                self.value = value
7✔
609
                self.instance = instance
7✔
610

611
        descriptor = Descriptor()
7✔
612

613
        class Proxy(self._getTargetClass()):
7✔
614
            attr = descriptor
7✔
615

616
        proxy = Proxy(object())
7✔
617
        proxy.attr = 42
7✔
618

619
        self.assertEqual(proxy.attr, descriptor)
7✔
620
        self.assertEqual(descriptor.value, 42)
7✔
621
        self.assertEqual(descriptor.instance, proxy)
7✔
622

623
    def test_descriptor__get___set___in_proxy_subclass(self):
7✔
624

625
        class Descriptor:
7✔
626
            value = None
7✔
627
            instance = None
7✔
628
            cls = None
7✔
629

630
            def __get__(self, instance, cls):
7✔
631
                self.cls = cls
7✔
632
                return self.value
7✔
633

634
            def __set__(self, instance, value):
7✔
635
                self.value = value
7✔
636
                self.instance = instance
7✔
637

638
        descriptor = Descriptor()
7✔
639
        descriptor.value = "descriptor value"
7✔
640

641
        class Proxy(self._getTargetClass()):
7✔
642
            attr = descriptor
7✔
643

644
        proxy = Proxy(object())
7✔
645
        self.assertEqual(proxy.attr, "descriptor value")
7✔
646
        self.assertEqual(descriptor.cls, Proxy)
7✔
647

648
        proxy.attr = 42
7✔
649

650
        self.assertEqual(descriptor.value, 42)
7✔
651
        self.assertEqual(descriptor.instance, proxy)
7✔
652

653
    def test_non_descriptor_in_proxy_subclass__dict__(self):
7✔
654
        # Non-descriptors in the class dict of the subclass
655
        # are always passed through to the wrapped instance
656
        class Proxy(self._getTargetClass()):
7✔
657
            attr = "constant value"
7✔
658

659
        proxy = Proxy(object())
7✔
660
        self.assertEqual(proxy.attr, "constant value")
7✔
661

662
        self.assertRaises(AttributeError, setattr, proxy, 'attr', 42)
7✔
663
        self.assertEqual(proxy.attr, "constant value")
7✔
664

665
    def _check_wrapping_builtin_returns_correct_provided_by(
7✔
666
            self, proxy_class, builtin_type):
667
        # We get the __implemented__ (fallback) of the type, not our own
668
        from zope.interface import Interface
7✔
669
        from zope.interface import classImplements
7✔
670
        from zope.interface import classImplementsOnly
7✔
671
        from zope.interface import implementedBy
7✔
672
        from zope.interface import providedBy
7✔
673

674
        # Set up the builtin interface
675
        class IFoo(Interface):
7✔
676
            pass
7✔
677
        impl_before = list(implementedBy(builtin_type))
7✔
678

679
        classImplements(builtin_type, IFoo)
7✔
680

681
        builtin = builtin_type()
7✔
682
        self.assertIn(IFoo, list(providedBy(builtin)))
7✔
683
        self.assertIn(IFoo, list(implementedBy(builtin_type)))
7✔
684

685
        try:
7✔
686
            # The asserts must be before we remove the interface
687
            # because there's a single object that gets mutated
688

689
            proxy_instance = proxy_class(builtin)
7✔
690
            provided_instance = providedBy(proxy_instance)
7✔
691
            self.assertIn(IFoo, list(provided_instance))
7✔
692

693
            proxy_type = proxy_class(builtin_type)
7✔
694
            from zope.interface.declarations import \
7✔
695
                BuiltinImplementationSpecifications
696
            self.assertIn(proxy_type, BuiltinImplementationSpecifications)
7✔
697
            self.assertIsNot(
7✔
698
                BuiltinImplementationSpecifications.get(proxy_type, self),
699
                self)
700
            provided_type = implementedBy(proxy_type)
7✔
701
            self.assertIn(IFoo, list(provided_type))
7✔
702
        finally:
703
            classImplementsOnly(builtin_type, *impl_before)
7✔
704

705
    def test_wrapping_builtin_type_returns_correct_provided_by(self):
7✔
706
        self._check_wrapping_builtin_returns_correct_provided_by(
7✔
707
            self._getTargetClass(), list)
708

709
    def _check_wrapping_builtin_with_subclass_returns_correct_provided_by(
7✔
710
            self, builtin_type):
711
        class Proxy(self._getTargetClass()):
7✔
712
            pass
7✔
713

714
        self._check_wrapping_builtin_returns_correct_provided_by(
7✔
715
            Proxy, builtin_type)
716
        # Our new class did not gain an __implemented__ attribute, unless we're
717
        # the pure-python version
718
        if hasattr(Proxy, '__implemented__'):  # pragma: no cover
719
            from zope.proxy import PyProxyBase
720
            self.assertIs(self._getTargetClass(), PyProxyBase)
721

722
    def test_wrapping_builtin_with_subclass_returns_correct_provided_by(self):
7✔
723
        self._check_wrapping_builtin_with_subclass_returns_correct_provided_by(
7✔
724
            list)
725

726
    def test_method_in_proxy_subclass(self):
7✔
727
        class Proxy(self._getTargetClass()):
7✔
728
            def __getitem__(self, k):
7✔
729
                return k
7✔
730

731
        proxy = Proxy(object())
7✔
732
        # Both when called by the interpreter, which bypasses
733
        # __getattribute__
734
        self.assertEqual(proxy[42], 42)
7✔
735
        # And when asked for as an attribute
736
        self.assertNotEqual(getattr(proxy, '__getitem__'), self)
7✔
737

738
    def test_string_to_int(self):
7✔
739
        proxy = self._makeOne("14")
7✔
740
        self.assertEqual(14, int(proxy))
7✔
741

742

743
# When the C extension is not available the target class will be the same as
744
# the Python implementation class. No need to run tests twice in that case.
745
@unittest.skipUnless(_c_available, 'C extension not available')
7✔
746
class ProxyBaseTestCase(PyProxyBaseTestCase):
7✔
747

748
    def _getTargetClass(self):
7✔
749
        from zope.proxy import ProxyBase
6✔
750
        return ProxyBase
6✔
751

752
    def test__reduce__raises(self):
7✔
753
        # With the C extension available the call to __reduce__
754
        # is delegated to copyreg._reduce_ex from the standard library.
755
        # That function raises TypeErrors and not pickle's exceptions
756
        proxy = self._makeOne('foo')
6✔
757

758
        with self.assertRaises(TypeError):
6✔
759
            proxy.__reduce__()
6✔
760

761
    def test__reduce_ex__raises(self):
7✔
762
        # With the C extension available the call to __reduce_ex__
763
        # is delegated to copyreg._reduce_ex from the standard library.
764
        # That function raises TypeErrors and not pickle's exceptions
765
        proxy = self._makeOne('foo')
6✔
766

767
        with self.assertRaises(TypeError):
6✔
768
            proxy.__reduce_ex__(0)
6✔
769

770

771
class Test_py__module(unittest.TestCase):
7✔
772
    # Historically, proxying __module__ has been troublesome,
773
    # especially when subclasses of the proxy class are involved;
774
    # there was also a discrepancy between the C and Python implementations
775
    # in that the C implementation only failed
776
    # Test_subclass__module:test__module__in_instance,
777
    # whereas the Python version failed every test.
778
    # See https://github.com/zopefoundation/zopetoolkit/pull/2#issuecomment-106075153  # noqa: E501 line too long
779
    # and https://github.com/zopefoundation/zope.proxy/pull/8
780

781
    def _getTargetClass(self):
7✔
782
        from zope.proxy import PyProxyBase
7✔
783
        return PyProxyBase
7✔
784

785
    def _makeProxy(self, obj):
7✔
786
        return self._getTargetClass()(obj)
7✔
787

788
    def _check_module(self, obj, expected):
7✔
789
        self.assertEqual(expected, obj.__module__)
7✔
790
        self.assertEqual(expected, self._makeProxy(obj).__module__)
7✔
791

792
    def test__module__in_instance(self):
7✔
793
        # We can find __module__ in an instance dict
794
        class Module:
7✔
795
            def __init__(self):
7✔
796
                self.__module__ = 'module'
7✔
797

798
        self._check_module(Module(), 'module')
7✔
799

800
    def test__module__in_class_instance(self):
7✔
801
        # We can find module in an instance of a class
802
        class Module:
7✔
803
            pass
7✔
804

805
        self._check_module(Module(), __name__)
7✔
806

807
    def test__module__in_class(self):
7✔
808
        # We can find module in a class itself
809
        class Module:
7✔
810
            pass
7✔
811
        self._check_module(Module, __name__)
7✔
812

813
    def test__module_in_eq_transitive(self):
7✔
814
        # An object that uses __module__ in its implementation
815
        # of __eq__ is transitively equal to a proxy of itself.
816
        # Seen with zope.interface.interface.Interface
817

818
        class Module:
7✔
819
            def __init__(self):
7✔
820
                self.__module__ = __name__
7✔
821

822
            def __eq__(self, other):
7✔
823
                return self.__module__ == other.__module__
7✔
824

825
        module = Module()
7✔
826
        # Sanity checks
827
        self.assertEqual(module, module)
7✔
828
        self.assertEqual(module.__module__, __name__)
7✔
829

830
        # transitive equal
831
        self.assertEqual(module, self._makeProxy(module))
7✔
832
        self.assertEqual(self._makeProxy(module), module)
7✔
833

834

835
class Test__module(Test_py__module):
7✔
836

837
    def _getTargetClass(self):
7✔
838
        from zope.proxy import ProxyBase
7✔
839
        return ProxyBase
7✔
840

841

842
class Test_py_subclass__module(Test_py__module):
7✔
843

844
    def _getTargetClass(self):
7✔
845
        class ProxySubclass(
7✔
846
                super(Test_py_subclass__module, self)._getTargetClass()):
847
            pass
7✔
848
        return ProxySubclass
7✔
849

850

851
class Test_subclass__module(Test__module):
7✔
852

853
    def _getTargetClass(self):
7✔
854
        class ProxySubclass(
7✔
855
                super(Test_subclass__module, self)._getTargetClass()):
856
            pass
7✔
857
        return ProxySubclass
7✔
858

859

860
class Test_py_getProxiedObject(unittest.TestCase):
7✔
861

862
    def _callFUT(self, *args):
7✔
863
        from zope.proxy import py_getProxiedObject
7✔
864
        return py_getProxiedObject(*args)
7✔
865

866
    def _makeProxy(self, obj):
7✔
867
        from zope.proxy import PyProxyBase
7✔
868
        return PyProxyBase(obj)
7✔
869

870
    def test_no_proxy(self):
7✔
871
        class C:
7✔
872
            pass
7✔
873
        c = C()
7✔
874
        self.assertIs(self._callFUT(c), c)
7✔
875

876
    def test_simple_proxy(self):
7✔
877
        class C:
7✔
878
            pass
7✔
879
        c = C()
7✔
880
        proxy = self._makeProxy(c)
7✔
881
        self.assertIs(self._callFUT(proxy), c)
7✔
882

883
    def test_nested_proxy(self):
7✔
884
        class C:
7✔
885
            pass
7✔
886
        c = C()
7✔
887
        proxy = self._makeProxy(c)
7✔
888
        proxy2 = self._makeProxy(proxy)
7✔
889
        self.assertIs(self._callFUT(proxy2), proxy)
7✔
890

891

892
class Test_getProxiedObject(Test_py_getProxiedObject):
7✔
893

894
    def _callFUT(self, *args):
7✔
895
        from zope.proxy import getProxiedObject
7✔
896
        return getProxiedObject(*args)
7✔
897

898
    def _makeProxy(self, obj):
7✔
899
        from zope.proxy import ProxyBase
7✔
900
        return ProxyBase(obj)
7✔
901

902

903
class Test_py_setProxiedObject(unittest.TestCase):
7✔
904

905
    def _callFUT(self, *args):
7✔
906
        from zope.proxy import py_setProxiedObject
7✔
907
        return py_setProxiedObject(*args)
7✔
908

909
    def _makeProxy(self, obj):
7✔
910
        from zope.proxy import PyProxyBase
7✔
911
        return PyProxyBase(obj)
7✔
912

913
    def test_no_proxy(self):
7✔
914
        class C:
7✔
915
            pass
7✔
916
        c1 = C()
7✔
917
        c2 = C()
7✔
918
        self.assertRaises(TypeError, self._callFUT, c1, c2)
7✔
919

920
    def test_w_proxy(self):
7✔
921
        class C:
7✔
922
            def __init__(self, name):
7✔
923
                self.name = name
7✔
924
        c1 = C('c1')
7✔
925
        c2 = C('c2')
7✔
926
        proxy = self._makeProxy(c1)
7✔
927
        self.assertEqual(proxy.name, 'c1')
7✔
928
        old = self._callFUT(proxy, c2)
7✔
929
        self.assertIs(old, c1)
7✔
930
        self.assertEqual(proxy.name, 'c2')
7✔
931

932
    def test_w_nested_proxy(self):
7✔
933
        class C:
7✔
934
            def __init__(self, name):
7✔
935
                self.name = name
7✔
936
        c1 = C('c1')
7✔
937
        c2 = C('c2')
7✔
938
        p1 = self._makeProxy(c1)
7✔
939
        proxy2 = self._makeProxy(c2)
7✔
940
        proxy = self._makeProxy(p1)
7✔
941
        self.assertEqual(proxy.name, 'c1')
7✔
942
        old = self._callFUT(proxy, proxy2)
7✔
943
        self.assertIs(old, p1)
7✔
944
        self.assertEqual(proxy.name, 'c2')
7✔
945

946

947
class Test_setProxiedObject(Test_py_setProxiedObject):
7✔
948

949
    def _callFUT(self, *args):
7✔
950
        from zope.proxy import setProxiedObject
7✔
951
        return setProxiedObject(*args)
7✔
952

953
    def _makeProxy(self, obj):
7✔
954
        from zope.proxy import ProxyBase
7✔
955
        return ProxyBase(obj)
7✔
956

957

958
class Test_py_isProxy(unittest.TestCase):
7✔
959

960
    def _callFUT(self, *args):
7✔
961
        from zope.proxy import py_isProxy
7✔
962
        return py_isProxy(*args)
7✔
963

964
    def _proxyClass(self):
7✔
965
        from zope.proxy import PyProxyBase
7✔
966
        return PyProxyBase
7✔
967

968
    def test_bare_instance(self):
7✔
969
        class C:
7✔
970
            pass
7✔
971
        c = C()
7✔
972
        self.assertFalse(self._callFUT(c))
7✔
973

974
    def test_proxy_no_class(self):
7✔
975
        class P1(self._proxyClass()):
7✔
976
            pass
7✔
977

978
        class C:
7✔
979
            pass
7✔
980
        c = C()
7✔
981
        p1 = P1(c)
7✔
982
        self.assertTrue(self._callFUT(p1))
7✔
983

984
    def test_proxy_w_same_class(self):
7✔
985
        class P1(self._proxyClass()):
7✔
986
            pass
7✔
987

988
        class C:
7✔
989
            pass
7✔
990
        c = C()
7✔
991
        p1 = P1(c)
7✔
992
        self.assertTrue(self._callFUT(p1, P1))
7✔
993

994
    def test_proxy_w_other_class(self):
7✔
995
        class P1(self._proxyClass()):
7✔
996
            pass
7✔
997

998
        class P2(self._proxyClass()):
7✔
999
            pass
7✔
1000

1001
        class C:
7✔
1002
            pass
7✔
1003
        c = C()
7✔
1004
        p1 = P1(c)
7✔
1005
        self.assertFalse(self._callFUT(p1, P2))
7✔
1006

1007

1008
class Test_isProxy(Test_py_isProxy):
7✔
1009

1010
    def _callFUT(self, *args):
7✔
1011
        from zope.proxy import isProxy
7✔
1012
        return isProxy(*args)
7✔
1013

1014
    def _proxyClass(self):
7✔
1015
        from zope.proxy import ProxyBase
7✔
1016
        return ProxyBase
7✔
1017

1018

1019
class Test_py_sameProxiedObjects(unittest.TestCase):
7✔
1020

1021
    def _callFUT(self, *args):
7✔
1022
        from zope.proxy import py_sameProxiedObjects
7✔
1023
        return py_sameProxiedObjects(*args)
7✔
1024

1025
    def _makeProxy(self, obj):
7✔
1026
        from zope.proxy import PyProxyBase
7✔
1027
        return PyProxyBase(obj)
7✔
1028

1029
    def _makeSecurityProxy(self, obj):
7✔
1030
        from zope.security.checker import CheckerPy
7✔
1031
        from zope.security.proxy import ProxyPy
7✔
1032
        checker = CheckerPy({})
7✔
1033
        return ProxyPy(obj, checker)
7✔
1034

1035
    def test_bare_instance_identical(self):
7✔
1036
        class C:
7✔
1037
            pass
7✔
1038
        c1 = C()
7✔
1039
        self.assertTrue(self._callFUT(c1, c1))
7✔
1040

1041
    def test_bare_instances_different(self):
7✔
1042
        class C:
7✔
1043
            pass
7✔
1044
        c1 = C()
7✔
1045
        c2 = C()
7✔
1046
        self.assertFalse(self._callFUT(c1, c2))
7✔
1047
        self.assertFalse(self._callFUT(c2, c1))
7✔
1048

1049
    def test_proxy_and_same_bare(self):
7✔
1050
        class C:
7✔
1051
            pass
7✔
1052
        c1 = C()
7✔
1053
        self.assertTrue(self._callFUT(self._makeProxy(c1), c1))
7✔
1054
        self.assertTrue(self._callFUT(c1, self._makeProxy(c1)))
7✔
1055

1056
    def test_proxy_and_other_bare(self):
7✔
1057
        class C:
7✔
1058
            pass
7✔
1059
        c1 = C()
7✔
1060
        c2 = C()
7✔
1061
        self.assertFalse(self._callFUT(self._makeProxy(c1), c2))
7✔
1062
        self.assertFalse(self._callFUT(c2, self._makeProxy(c1)))
7✔
1063

1064
    def test_proxies_w_same_bare(self):
7✔
1065
        _mP = self._makeProxy
7✔
1066

1067
        class C:
7✔
1068
            pass
7✔
1069
        c1 = C()
7✔
1070
        self.assertTrue(self._callFUT(_mP(c1), _mP(c1)))
7✔
1071

1072
    def test_proxies_w_other_bare(self):
7✔
1073
        _mP = self._makeProxy
7✔
1074

1075
        class C:
7✔
1076
            pass
7✔
1077
        c1 = C()
7✔
1078
        c2 = C()
7✔
1079
        self.assertFalse(self._callFUT(_mP(c1), _mP(c2)))
7✔
1080
        self.assertFalse(self._callFUT(_mP(c2), _mP(c1)))
7✔
1081

1082
    def test_nested_proxy_and_same_bare(self):
7✔
1083
        _mP = self._makeProxy
7✔
1084

1085
        class C:
7✔
1086
            pass
7✔
1087
        c1 = C()
7✔
1088
        self.assertTrue(self._callFUT(_mP(_mP(c1)), c1))
7✔
1089
        self.assertTrue(self._callFUT(c1, _mP(_mP(c1))))
7✔
1090

1091
    def test_nested_proxy_and_other_bare(self):
7✔
1092
        _mP = self._makeProxy
7✔
1093

1094
        class C:
7✔
1095
            pass
7✔
1096
        c1 = C()
7✔
1097
        c2 = C()
7✔
1098
        self.assertFalse(self._callFUT(_mP(_mP(c1)), c2))
7✔
1099
        self.assertFalse(self._callFUT(c2, _mP(_mP(c1))))
7✔
1100

1101
    @unittest.skipUnless(_HAVE_ZOPE_SECURITY, 'zope.security missing')
7✔
1102
    def test_security_proxy(self):
7✔
1103
        class C:
7✔
1104
            pass
7✔
1105
        c1 = C()
7✔
1106
        proxy1 = self._makeSecurityProxy(c1)
7✔
1107
        proxy1_2 = self._makeSecurityProxy(c1)
7✔
1108

1109
        self.assertTrue(self._callFUT(proxy1, proxy1))
7✔
1110
        self.assertTrue(self._callFUT(proxy1, proxy1_2))
7✔
1111

1112
        c2 = C()
7✔
1113
        proxy2 = self._makeSecurityProxy(c2)
7✔
1114
        self.assertFalse(self._callFUT(proxy1, proxy2))
7✔
1115

1116

1117
class Test_sameProxiedObjects(Test_py_sameProxiedObjects):
7✔
1118

1119
    def _callFUT(self, *args):
7✔
1120
        from zope.proxy import sameProxiedObjects
7✔
1121
        return sameProxiedObjects(*args)
7✔
1122

1123
    def _makeProxy(self, obj):
7✔
1124
        from zope.proxy import ProxyBase
7✔
1125
        return ProxyBase(obj)
7✔
1126

1127
    def _makeSecurityProxy(self, obj):
7✔
1128
        from zope.security.checker import Checker
7✔
1129
        from zope.security.proxy import Proxy
7✔
1130
        checker = Checker({})
7✔
1131
        return Proxy(obj, checker)
7✔
1132

1133

1134
class Test_py_queryProxy(unittest.TestCase):
7✔
1135

1136
    def _callFUT(self, *args):
7✔
1137
        from zope.proxy import py_queryProxy
7✔
1138
        return py_queryProxy(*args)
7✔
1139

1140
    def _proxyClass(self):
7✔
1141
        from zope.proxy import PyProxyBase
7✔
1142
        return PyProxyBase
7✔
1143

1144
    def test_bare_instance(self):
7✔
1145
        class C:
7✔
1146
            pass
7✔
1147
        c = C()
7✔
1148
        self.assertEqual(self._callFUT(c), None)
7✔
1149

1150
    def test_proxy_no_class(self):
7✔
1151
        class P1(self._proxyClass()):
7✔
1152
            pass
7✔
1153

1154
        class C:
7✔
1155
            pass
7✔
1156
        c = C()
7✔
1157
        p1 = P1(c)
7✔
1158
        self.assertIs(self._callFUT(p1), p1)
7✔
1159

1160
    def test_proxy_w_same_class(self):
7✔
1161
        class P1(self._proxyClass()):
7✔
1162
            pass
7✔
1163

1164
        class C:
7✔
1165
            pass
7✔
1166
        c = C()
7✔
1167
        p1 = P1(c)
7✔
1168
        self.assertIs(self._callFUT(p1, P1), p1)
7✔
1169
        self.assertIs(self._callFUT(p1, P1, 42), p1)
7✔
1170

1171
    def test_proxy_w_other_class(self):
7✔
1172
        class P1(self._proxyClass()):
7✔
1173
            pass
7✔
1174

1175
        class P2(self._proxyClass()):
7✔
1176
            pass
7✔
1177

1178
        class C:
7✔
1179
            pass
7✔
1180
        c = C()
7✔
1181
        p1 = P1(c)
7✔
1182
        self.assertEqual(self._callFUT(p1, P2), None)
7✔
1183
        self.assertEqual(self._callFUT(p1, P2, 42), 42)
7✔
1184

1185
    def test_proxy_w_base_class(self):
7✔
1186
        class P1(self._proxyClass()):
7✔
1187
            pass
7✔
1188

1189
        class P2(self._proxyClass()):
7✔
1190
            pass
7✔
1191

1192
        class C:
7✔
1193
            pass
7✔
1194
        c = C()
7✔
1195
        p1 = P1(c)
7✔
1196
        self.assertIs(self._callFUT(p1, self._proxyClass()), p1)
7✔
1197
        self.assertIs(self._callFUT(p1, self._proxyClass(), 42), p1)
7✔
1198

1199

1200
class Test_queryProxy(Test_py_queryProxy):
7✔
1201

1202
    def _callFUT(self, *args):
7✔
1203
        from zope.proxy import queryProxy
7✔
1204
        return queryProxy(*args)
7✔
1205

1206
    def _proxyClass(self):
7✔
1207
        from zope.proxy import ProxyBase
7✔
1208
        return ProxyBase
7✔
1209

1210

1211
class Test_py_queryInnerProxy(unittest.TestCase):
7✔
1212

1213
    def _callFUT(self, *args):
7✔
1214
        from zope.proxy import py_queryInnerProxy
7✔
1215
        return py_queryInnerProxy(*args)
7✔
1216

1217
    def _proxyClass(self):
7✔
1218
        from zope.proxy import PyProxyBase
7✔
1219
        return PyProxyBase
7✔
1220

1221
    def test_bare_instance(self):
7✔
1222
        class C:
7✔
1223
            pass
7✔
1224
        c = C()
7✔
1225
        self.assertEqual(self._callFUT(c), None)
7✔
1226

1227
    def test_proxy_no_class(self):
7✔
1228
        class P1(self._proxyClass()):
7✔
1229
            pass
7✔
1230

1231
        class C:
7✔
1232
            pass
7✔
1233
        c = C()
7✔
1234
        p1 = P1(c)
7✔
1235
        self.assertIs(self._callFUT(p1), p1)
7✔
1236

1237
    def test_proxy_w_same_class(self):
7✔
1238
        class P1(self._proxyClass()):
7✔
1239
            pass
7✔
1240

1241
        class C:
7✔
1242
            pass
7✔
1243
        c = C()
7✔
1244
        p1 = P1(c)
7✔
1245
        self.assertIs(self._callFUT(p1, P1), p1)
7✔
1246
        self.assertIs(self._callFUT(p1, P1, 42), p1)
7✔
1247

1248
    def test_nested_proxy(self):
7✔
1249
        class P1(self._proxyClass()):
7✔
1250
            pass
7✔
1251

1252
        class P2(self._proxyClass()):
7✔
1253
            pass
7✔
1254

1255
        class C:
7✔
1256
            pass
7✔
1257
        c = C()
7✔
1258
        p1 = P1(c)
7✔
1259
        proxy2 = P2(p1)
7✔
1260
        self.assertIs(self._callFUT(proxy2, P1), p1)
7✔
1261
        self.assertIs(self._callFUT(proxy2, P1, 42), p1)
7✔
1262
        self.assertIs(self._callFUT(proxy2, P2), proxy2)
7✔
1263
        self.assertIs(self._callFUT(proxy2, P2, 42), proxy2)
7✔
1264

1265
    def test_re_nested_proxy(self):
7✔
1266
        class P1(self._proxyClass()):
7✔
1267
            pass
7✔
1268

1269
        class P2(self._proxyClass()):
7✔
1270
            pass
7✔
1271

1272
        class C:
7✔
1273
            pass
7✔
1274
        c = C()
7✔
1275
        p1 = P1(c)
7✔
1276
        proxy2 = P2(p1)
7✔
1277
        proxy3 = P1(proxy2)
7✔
1278
        self.assertIs(self._callFUT(proxy3, P1), p1)
7✔
1279
        self.assertIs(self._callFUT(proxy3, P1, 42), p1)
7✔
1280
        self.assertIs(self._callFUT(proxy3, P2), proxy2)
7✔
1281
        self.assertIs(self._callFUT(proxy3, P2, 42), proxy2)
7✔
1282

1283

1284
class Test_queryInnerProxy(Test_py_queryInnerProxy):
7✔
1285

1286
    def _callFUT(self, *args):
7✔
1287
        from zope.proxy import queryInnerProxy
7✔
1288
        return queryInnerProxy(*args)
7✔
1289

1290
    def _proxyClass(self):
7✔
1291
        from zope.proxy import ProxyBase
7✔
1292
        return ProxyBase
7✔
1293

1294

1295
class Test_py_removeAllProxies(unittest.TestCase):
7✔
1296

1297
    def _callFUT(self, *args):
7✔
1298
        from zope.proxy import py_removeAllProxies
7✔
1299
        return py_removeAllProxies(*args)
7✔
1300

1301
    def _makeProxy(self, obj):
7✔
1302
        from zope.proxy import PyProxyBase
7✔
1303
        return PyProxyBase(obj)
7✔
1304

1305
    def _makeSecurityProxy(self, obj):
7✔
1306
        from zope.security.proxy import ProxyPy
7✔
1307
        checker = object()
7✔
1308
        return ProxyPy(obj, checker)
7✔
1309

1310
    def test_no_proxy(self):
7✔
1311
        class C:
7✔
1312
            pass
7✔
1313
        c = C()
7✔
1314
        self.assertIs(self._callFUT(c), c)
7✔
1315

1316
    def test_simple_proxy(self):
7✔
1317
        class C:
7✔
1318
            pass
7✔
1319
        c = C()
7✔
1320
        proxy = self._makeProxy(c)
7✔
1321
        self.assertIs(self._callFUT(proxy), c)
7✔
1322

1323
    def test_nested_proxy(self):
7✔
1324
        class C:
7✔
1325
            pass
7✔
1326
        c = C()
7✔
1327
        proxy = self._makeProxy(c)
7✔
1328
        proxy2 = self._makeProxy(proxy)
7✔
1329
        self.assertIs(self._callFUT(proxy2), c)
7✔
1330

1331
    @unittest.skipUnless(_HAVE_ZOPE_SECURITY, 'zope.security missing')
7✔
1332
    def test_security_proxy(self):
7✔
1333
        class C:
7✔
1334
            pass
7✔
1335
        c = C()
7✔
1336
        proxy = self._makeSecurityProxy(c)
7✔
1337
        self.assertIs(self._callFUT(proxy), c)
7✔
1338

1339

1340
class Test_removeAllProxies(Test_py_removeAllProxies):
7✔
1341

1342
    def _callFUT(self, *args):
7✔
1343
        from zope.proxy import removeAllProxies
7✔
1344
        return removeAllProxies(*args)
7✔
1345

1346
    def _makeProxy(self, obj):
7✔
1347
        from zope.proxy import ProxyBase
7✔
1348
        return ProxyBase(obj)
7✔
1349

1350
    def _makeSecurityProxy(self, obj):
7✔
1351
        from zope.security.proxy import Proxy
7✔
1352
        checker = object()
7✔
1353
        return Proxy(obj, checker)
7✔
1354

1355

1356
class Test_ProxyIterator(unittest.TestCase):
7✔
1357

1358
    def _callFUT(self, *args):
7✔
1359
        from zope.proxy import ProxyIterator
7✔
1360
        return ProxyIterator(*args)
7✔
1361

1362
    def test_no_proxy(self):
7✔
1363
        class C:
7✔
1364
            pass
7✔
1365
        c = C()
7✔
1366
        self.assertEqual(list(self._callFUT(c)), [c])
7✔
1367

1368
    def test_w_simple_proxy(self):
7✔
1369
        from zope.proxy import ProxyBase
7✔
1370

1371
        class C:
7✔
1372
            pass
7✔
1373
        c = C()
7✔
1374
        proxy = ProxyBase(c)
7✔
1375
        self.assertEqual(list(self._callFUT(proxy)), [proxy, c])
7✔
1376

1377
    def test_w_nested_proxies(self):
7✔
1378
        from zope.proxy import ProxyBase
7✔
1379

1380
        class C:
7✔
1381
            pass
7✔
1382
        c = C()
7✔
1383
        proxy = ProxyBase(c)
7✔
1384
        proxy2 = ProxyBase(proxy)
7✔
1385
        proxy3 = ProxyBase(proxy2)
7✔
1386
        proxy4 = ProxyBase(proxy3)
7✔
1387
        self.assertEqual(list(self._callFUT(proxy4)),
7✔
1388
                         [proxy4, proxy3, proxy2, proxy, c])
1389

1390

1391
class Test_nonOverridable(unittest.TestCase):
7✔
1392

1393
    def test_it(self):
7✔
1394
        from zope.proxy import ProxyBase
7✔
1395
        from zope.proxy import non_overridable
7✔
1396

1397
        class Proxy(ProxyBase):
7✔
1398
            def who(self):
7✔
1399
                raise AssertionError("Not called")
1400

1401
            @non_overridable
7✔
1402
            def what(self):
7✔
1403
                return 'PROXY'
7✔
1404

1405
        class Foo:
7✔
1406
            def who(self):
7✔
1407
                return 'FOO'
7✔
1408

1409
            def what(self):
7✔
1410
                return 'FOO'
7✔
1411
        p0 = ProxyBase(Foo())
7✔
1412
        self.assertEqual(p0.who(), 'FOO')
7✔
1413
        self.assertEqual(p0.what(), 'FOO')
7✔
1414
        proxy = Proxy(Foo())
7✔
1415
        self.assertEqual(proxy.who(), 'FOO')
7✔
1416
        self.assertEqual(proxy.what(), 'PROXY')
7✔
1417

1418

1419
class TestEmptyInterfaceDescriptor(unittest.TestCase):
7✔
1420

1421
    def _makeOne(self):
7✔
1422
        from zope.proxy import _EmptyInterfaceDescriptor
7✔
1423

1424
        class It:
7✔
1425
            feature = _EmptyInterfaceDescriptor()
7✔
1426
        return It()
7✔
1427

1428
    def test_set(self):
7✔
1429
        it = self._makeOne()
7✔
1430
        with self.assertRaises(TypeError):
7✔
1431
            it.feature = 42
7✔
1432

1433
    def test_delete(self):
7✔
1434
        it = self._makeOne()
7✔
1435
        del it.feature
7✔
1436
        with self.assertRaises(AttributeError):
7✔
1437
            getattr(it, 'feature')
7✔
1438

1439
    def test_iter(self):
7✔
1440
        it = type(self._makeOne())
7✔
1441
        feature = it.__dict__['feature']
7✔
1442
        self.assertEqual([], list(feature))
7✔
1443

1444

1445
class Comparable:
7✔
1446
    def __init__(self, value):
7✔
1447
        self.value = value
7✔
1448

1449
    def __eq__(self, other):
7✔
1450
        return self.value == getattr(other, 'value', other)
7✔
1451

1452
    def __ne__(self, other):
7✔
1453
        return not self.__eq__(other)
7✔
1454

1455
    def __lt__(self, other):
7✔
1456
        return self.value < getattr(other, 'value', other)
7✔
1457

1458
    def __ge__(self, other):
7✔
1459
        return not self.__lt__(other)
7✔
1460

1461
    def __le__(self, other):
7✔
1462
        return self.value <= getattr(other, 'value', other)
7✔
1463

1464
    def __gt__(self, other):
7✔
1465
        return not self.__le__(other)
7✔
1466

1467
    def __repr__(self):  # pragma: no cover
1468
        return "<Comparable: %r>" % self.value
1469

1470

1471
def test_suite():
7✔
1472
    return unittest.defaultTestLoader.loadTestsFromName(__name__)
7✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc