• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1import gc
2import sys
3import unittest
4import collections
5import weakref
6import operator
7import contextlib
8import copy
9import threading
10import time
11import random
12
13from test import support
14from test.support import script_helper
15
16# Used in ReferencesTestCase.test_ref_created_during_del() .
17ref_from_del = None
18
19# Used by FinalizeTestCase as a global that may be replaced by None
20# when the interpreter shuts down.
21_global_var = 'foobar'
22
23class C:
24    def method(self):
25        pass
26
27
28class Callable:
29    bar = None
30
31    def __call__(self, x):
32        self.bar = x
33
34
35def create_function():
36    def f(): pass
37    return f
38
39def create_bound_method():
40    return C().method
41
42
43class Object:
44    def __init__(self, arg):
45        self.arg = arg
46    def __repr__(self):
47        return "<Object %r>" % self.arg
48    def __eq__(self, other):
49        if isinstance(other, Object):
50            return self.arg == other.arg
51        return NotImplemented
52    def __lt__(self, other):
53        if isinstance(other, Object):
54            return self.arg < other.arg
55        return NotImplemented
56    def __hash__(self):
57        return hash(self.arg)
58    def some_method(self):
59        return 4
60    def other_method(self):
61        return 5
62
63
64class RefCycle:
65    def __init__(self):
66        self.cycle = self
67
68
69class TestBase(unittest.TestCase):
70
71    def setUp(self):
72        self.cbcalled = 0
73
74    def callback(self, ref):
75        self.cbcalled += 1
76
77
78@contextlib.contextmanager
79def collect_in_thread(period=0.0001):
80    """
81    Ensure GC collections happen in a different thread, at a high frequency.
82    """
83    please_stop = False
84
85    def collect():
86        while not please_stop:
87            time.sleep(period)
88            gc.collect()
89
90    with support.disable_gc():
91        t = threading.Thread(target=collect)
92        t.start()
93        try:
94            yield
95        finally:
96            please_stop = True
97            t.join()
98
99
100class ReferencesTestCase(TestBase):
101
102    def test_basic_ref(self):
103        self.check_basic_ref(C)
104        self.check_basic_ref(create_function)
105        self.check_basic_ref(create_bound_method)
106
107        # Just make sure the tp_repr handler doesn't raise an exception.
108        # Live reference:
109        o = C()
110        wr = weakref.ref(o)
111        repr(wr)
112        # Dead reference:
113        del o
114        repr(wr)
115
116    def test_basic_callback(self):
117        self.check_basic_callback(C)
118        self.check_basic_callback(create_function)
119        self.check_basic_callback(create_bound_method)
120
121    @support.cpython_only
122    def test_cfunction(self):
123        import _testcapi
124        create_cfunction = _testcapi.create_cfunction
125        f = create_cfunction()
126        wr = weakref.ref(f)
127        self.assertIs(wr(), f)
128        del f
129        self.assertIsNone(wr())
130        self.check_basic_ref(create_cfunction)
131        self.check_basic_callback(create_cfunction)
132
133    def test_multiple_callbacks(self):
134        o = C()
135        ref1 = weakref.ref(o, self.callback)
136        ref2 = weakref.ref(o, self.callback)
137        del o
138        self.assertIsNone(ref1(), "expected reference to be invalidated")
139        self.assertIsNone(ref2(), "expected reference to be invalidated")
140        self.assertEqual(self.cbcalled, 2,
141                     "callback not called the right number of times")
142
143    def test_multiple_selfref_callbacks(self):
144        # Make sure all references are invalidated before callbacks are called
145        #
146        # What's important here is that we're using the first
147        # reference in the callback invoked on the second reference
148        # (the most recently created ref is cleaned up first).  This
149        # tests that all references to the object are invalidated
150        # before any of the callbacks are invoked, so that we only
151        # have one invocation of _weakref.c:cleanup_helper() active
152        # for a particular object at a time.
153        #
154        def callback(object, self=self):
155            self.ref()
156        c = C()
157        self.ref = weakref.ref(c, callback)
158        ref1 = weakref.ref(c, callback)
159        del c
160
161    def test_constructor_kwargs(self):
162        c = C()
163        self.assertRaises(TypeError, weakref.ref, c, callback=None)
164
165    def test_proxy_ref(self):
166        o = C()
167        o.bar = 1
168        ref1 = weakref.proxy(o, self.callback)
169        ref2 = weakref.proxy(o, self.callback)
170        del o
171
172        def check(proxy):
173            proxy.bar
174
175        self.assertRaises(ReferenceError, check, ref1)
176        self.assertRaises(ReferenceError, check, ref2)
177        self.assertRaises(ReferenceError, bool, weakref.proxy(C()))
178        self.assertEqual(self.cbcalled, 2)
179
180    def check_basic_ref(self, factory):
181        o = factory()
182        ref = weakref.ref(o)
183        self.assertIsNotNone(ref(),
184                     "weak reference to live object should be live")
185        o2 = ref()
186        self.assertIs(o, o2,
187                     "<ref>() should return original object if live")
188
189    def check_basic_callback(self, factory):
190        self.cbcalled = 0
191        o = factory()
192        ref = weakref.ref(o, self.callback)
193        del o
194        self.assertEqual(self.cbcalled, 1,
195                     "callback did not properly set 'cbcalled'")
196        self.assertIsNone(ref(),
197                     "ref2 should be dead after deleting object reference")
198
199    def test_ref_reuse(self):
200        o = C()
201        ref1 = weakref.ref(o)
202        # create a proxy to make sure that there's an intervening creation
203        # between these two; it should make no difference
204        proxy = weakref.proxy(o)
205        ref2 = weakref.ref(o)
206        self.assertIs(ref1, ref2,
207                     "reference object w/out callback should be re-used")
208
209        o = C()
210        proxy = weakref.proxy(o)
211        ref1 = weakref.ref(o)
212        ref2 = weakref.ref(o)
213        self.assertIs(ref1, ref2,
214                     "reference object w/out callback should be re-used")
215        self.assertEqual(weakref.getweakrefcount(o), 2,
216                     "wrong weak ref count for object")
217        del proxy
218        self.assertEqual(weakref.getweakrefcount(o), 1,
219                     "wrong weak ref count for object after deleting proxy")
220
221    def test_proxy_reuse(self):
222        o = C()
223        proxy1 = weakref.proxy(o)
224        ref = weakref.ref(o)
225        proxy2 = weakref.proxy(o)
226        self.assertIs(proxy1, proxy2,
227                     "proxy object w/out callback should have been re-used")
228
229    def test_basic_proxy(self):
230        o = C()
231        self.check_proxy(o, weakref.proxy(o))
232
233        L = collections.UserList()
234        p = weakref.proxy(L)
235        self.assertFalse(p, "proxy for empty UserList should be false")
236        p.append(12)
237        self.assertEqual(len(L), 1)
238        self.assertTrue(p, "proxy for non-empty UserList should be true")
239        p[:] = [2, 3]
240        self.assertEqual(len(L), 2)
241        self.assertEqual(len(p), 2)
242        self.assertIn(3, p, "proxy didn't support __contains__() properly")
243        p[1] = 5
244        self.assertEqual(L[1], 5)
245        self.assertEqual(p[1], 5)
246        L2 = collections.UserList(L)
247        p2 = weakref.proxy(L2)
248        self.assertEqual(p, p2)
249        ## self.assertEqual(repr(L2), repr(p2))
250        L3 = collections.UserList(range(10))
251        p3 = weakref.proxy(L3)
252        self.assertEqual(L3[:], p3[:])
253        self.assertEqual(L3[5:], p3[5:])
254        self.assertEqual(L3[:5], p3[:5])
255        self.assertEqual(L3[2:5], p3[2:5])
256
257    def test_proxy_unicode(self):
258        # See bug 5037
259        class C(object):
260            def __str__(self):
261                return "string"
262            def __bytes__(self):
263                return b"bytes"
264        instance = C()
265        self.assertIn("__bytes__", dir(weakref.proxy(instance)))
266        self.assertEqual(bytes(weakref.proxy(instance)), b"bytes")
267
268    def test_proxy_index(self):
269        class C:
270            def __index__(self):
271                return 10
272        o = C()
273        p = weakref.proxy(o)
274        self.assertEqual(operator.index(p), 10)
275
276    def test_proxy_div(self):
277        class C:
278            def __floordiv__(self, other):
279                return 42
280            def __ifloordiv__(self, other):
281                return 21
282        o = C()
283        p = weakref.proxy(o)
284        self.assertEqual(p // 5, 42)
285        p //= 5
286        self.assertEqual(p, 21)
287
288    def test_proxy_matmul(self):
289        class C:
290            def __matmul__(self, other):
291                return 1729
292            def __rmatmul__(self, other):
293                return -163
294            def __imatmul__(self, other):
295                return 561
296        o = C()
297        p = weakref.proxy(o)
298        self.assertEqual(p @ 5, 1729)
299        self.assertEqual(5 @ p, -163)
300        p @= 5
301        self.assertEqual(p, 561)
302
303    # The PyWeakref_* C API is documented as allowing either NULL or
304    # None as the value for the callback, where either means "no
305    # callback".  The "no callback" ref and proxy objects are supposed
306    # to be shared so long as they exist by all callers so long as
307    # they are active.  In Python 2.3.3 and earlier, this guarantee
308    # was not honored, and was broken in different ways for
309    # PyWeakref_NewRef() and PyWeakref_NewProxy().  (Two tests.)
310
311    def test_shared_ref_without_callback(self):
312        self.check_shared_without_callback(weakref.ref)
313
314    def test_shared_proxy_without_callback(self):
315        self.check_shared_without_callback(weakref.proxy)
316
317    def check_shared_without_callback(self, makeref):
318        o = Object(1)
319        p1 = makeref(o, None)
320        p2 = makeref(o, None)
321        self.assertIs(p1, p2, "both callbacks were None in the C API")
322        del p1, p2
323        p1 = makeref(o)
324        p2 = makeref(o, None)
325        self.assertIs(p1, p2, "callbacks were NULL, None in the C API")
326        del p1, p2
327        p1 = makeref(o)
328        p2 = makeref(o)
329        self.assertIs(p1, p2, "both callbacks were NULL in the C API")
330        del p1, p2
331        p1 = makeref(o, None)
332        p2 = makeref(o)
333        self.assertIs(p1, p2, "callbacks were None, NULL in the C API")
334
335    def test_callable_proxy(self):
336        o = Callable()
337        ref1 = weakref.proxy(o)
338
339        self.check_proxy(o, ref1)
340
341        self.assertIs(type(ref1), weakref.CallableProxyType,
342                     "proxy is not of callable type")
343        ref1('twinkies!')
344        self.assertEqual(o.bar, 'twinkies!',
345                     "call through proxy not passed through to original")
346        ref1(x='Splat.')
347        self.assertEqual(o.bar, 'Splat.',
348                     "call through proxy not passed through to original")
349
350        # expect due to too few args
351        self.assertRaises(TypeError, ref1)
352
353        # expect due to too many args
354        self.assertRaises(TypeError, ref1, 1, 2, 3)
355
356    def check_proxy(self, o, proxy):
357        o.foo = 1
358        self.assertEqual(proxy.foo, 1,
359                     "proxy does not reflect attribute addition")
360        o.foo = 2
361        self.assertEqual(proxy.foo, 2,
362                     "proxy does not reflect attribute modification")
363        del o.foo
364        self.assertFalse(hasattr(proxy, 'foo'),
365                     "proxy does not reflect attribute removal")
366
367        proxy.foo = 1
368        self.assertEqual(o.foo, 1,
369                     "object does not reflect attribute addition via proxy")
370        proxy.foo = 2
371        self.assertEqual(o.foo, 2,
372            "object does not reflect attribute modification via proxy")
373        del proxy.foo
374        self.assertFalse(hasattr(o, 'foo'),
375                     "object does not reflect attribute removal via proxy")
376
377    def test_proxy_deletion(self):
378        # Test clearing of SF bug #762891
379        class Foo:
380            result = None
381            def __delitem__(self, accessor):
382                self.result = accessor
383        g = Foo()
384        f = weakref.proxy(g)
385        del f[0]
386        self.assertEqual(f.result, 0)
387
388    def test_proxy_bool(self):
389        # Test clearing of SF bug #1170766
390        class List(list): pass
391        lyst = List()
392        self.assertEqual(bool(weakref.proxy(lyst)), bool(lyst))
393
394    def test_proxy_iter(self):
395        # Test fails with a debug build of the interpreter
396        # (see bpo-38395).
397
398        obj = None
399
400        class MyObj:
401            def __iter__(self):
402                nonlocal obj
403                del obj
404                return NotImplemented
405
406        obj = MyObj()
407        p = weakref.proxy(obj)
408        with self.assertRaises(TypeError):
409            # "blech" in p calls MyObj.__iter__ through the proxy,
410            # without keeping a reference to the real object, so it
411            # can be killed in the middle of the call
412            "blech" in p
413
414    def test_getweakrefcount(self):
415        o = C()
416        ref1 = weakref.ref(o)
417        ref2 = weakref.ref(o, self.callback)
418        self.assertEqual(weakref.getweakrefcount(o), 2,
419                     "got wrong number of weak reference objects")
420
421        proxy1 = weakref.proxy(o)
422        proxy2 = weakref.proxy(o, self.callback)
423        self.assertEqual(weakref.getweakrefcount(o), 4,
424                     "got wrong number of weak reference objects")
425
426        del ref1, ref2, proxy1, proxy2
427        self.assertEqual(weakref.getweakrefcount(o), 0,
428                     "weak reference objects not unlinked from"
429                     " referent when discarded.")
430
431        # assumes ints do not support weakrefs
432        self.assertEqual(weakref.getweakrefcount(1), 0,
433                     "got wrong number of weak reference objects for int")
434
435    def test_getweakrefs(self):
436        o = C()
437        ref1 = weakref.ref(o, self.callback)
438        ref2 = weakref.ref(o, self.callback)
439        del ref1
440        self.assertEqual(weakref.getweakrefs(o), [ref2],
441                     "list of refs does not match")
442
443        o = C()
444        ref1 = weakref.ref(o, self.callback)
445        ref2 = weakref.ref(o, self.callback)
446        del ref2
447        self.assertEqual(weakref.getweakrefs(o), [ref1],
448                     "list of refs does not match")
449
450        del ref1
451        self.assertEqual(weakref.getweakrefs(o), [],
452                     "list of refs not cleared")
453
454        # assumes ints do not support weakrefs
455        self.assertEqual(weakref.getweakrefs(1), [],
456                     "list of refs does not match for int")
457
458    def test_newstyle_number_ops(self):
459        class F(float):
460            pass
461        f = F(2.0)
462        p = weakref.proxy(f)
463        self.assertEqual(p + 1.0, 3.0)
464        self.assertEqual(1.0 + p, 3.0)  # this used to SEGV
465
466    def test_callbacks_protected(self):
467        # Callbacks protected from already-set exceptions?
468        # Regression test for SF bug #478534.
469        class BogusError(Exception):
470            pass
471        data = {}
472        def remove(k):
473            del data[k]
474        def encapsulate():
475            f = lambda : ()
476            data[weakref.ref(f, remove)] = None
477            raise BogusError
478        try:
479            encapsulate()
480        except BogusError:
481            pass
482        else:
483            self.fail("exception not properly restored")
484        try:
485            encapsulate()
486        except BogusError:
487            pass
488        else:
489            self.fail("exception not properly restored")
490
491    def test_sf_bug_840829(self):
492        # "weakref callbacks and gc corrupt memory"
493        # subtype_dealloc erroneously exposed a new-style instance
494        # already in the process of getting deallocated to gc,
495        # causing double-deallocation if the instance had a weakref
496        # callback that triggered gc.
497        # If the bug exists, there probably won't be an obvious symptom
498        # in a release build.  In a debug build, a segfault will occur
499        # when the second attempt to remove the instance from the "list
500        # of all objects" occurs.
501
502        import gc
503
504        class C(object):
505            pass
506
507        c = C()
508        wr = weakref.ref(c, lambda ignore: gc.collect())
509        del c
510
511        # There endeth the first part.  It gets worse.
512        del wr
513
514        c1 = C()
515        c1.i = C()
516        wr = weakref.ref(c1.i, lambda ignore: gc.collect())
517
518        c2 = C()
519        c2.c1 = c1
520        del c1  # still alive because c2 points to it
521
522        # Now when subtype_dealloc gets called on c2, it's not enough just
523        # that c2 is immune from gc while the weakref callbacks associated
524        # with c2 execute (there are none in this 2nd half of the test, btw).
525        # subtype_dealloc goes on to call the base classes' deallocs too,
526        # so any gc triggered by weakref callbacks associated with anything
527        # torn down by a base class dealloc can also trigger double
528        # deallocation of c2.
529        del c2
530
531    def test_callback_in_cycle_1(self):
532        import gc
533
534        class J(object):
535            pass
536
537        class II(object):
538            def acallback(self, ignore):
539                self.J
540
541        I = II()
542        I.J = J
543        I.wr = weakref.ref(J, I.acallback)
544
545        # Now J and II are each in a self-cycle (as all new-style class
546        # objects are, since their __mro__ points back to them).  I holds
547        # both a weak reference (I.wr) and a strong reference (I.J) to class
548        # J.  I is also in a cycle (I.wr points to a weakref that references
549        # I.acallback).  When we del these three, they all become trash, but
550        # the cycles prevent any of them from getting cleaned up immediately.
551        # Instead they have to wait for cyclic gc to deduce that they're
552        # trash.
553        #
554        # gc used to call tp_clear on all of them, and the order in which
555        # it does that is pretty accidental.  The exact order in which we
556        # built up these things manages to provoke gc into running tp_clear
557        # in just the right order (I last).  Calling tp_clear on II leaves
558        # behind an insane class object (its __mro__ becomes NULL).  Calling
559        # tp_clear on J breaks its self-cycle, but J doesn't get deleted
560        # just then because of the strong reference from I.J.  Calling
561        # tp_clear on I starts to clear I's __dict__, and just happens to
562        # clear I.J first -- I.wr is still intact.  That removes the last
563        # reference to J, which triggers the weakref callback.  The callback
564        # tries to do "self.J", and instances of new-style classes look up
565        # attributes ("J") in the class dict first.  The class (II) wants to
566        # search II.__mro__, but that's NULL.   The result was a segfault in
567        # a release build, and an assert failure in a debug build.
568        del I, J, II
569        gc.collect()
570
571    def test_callback_in_cycle_2(self):
572        import gc
573
574        # This is just like test_callback_in_cycle_1, except that II is an
575        # old-style class.  The symptom is different then:  an instance of an
576        # old-style class looks in its own __dict__ first.  'J' happens to
577        # get cleared from I.__dict__ before 'wr', and 'J' was never in II's
578        # __dict__, so the attribute isn't found.  The difference is that
579        # the old-style II doesn't have a NULL __mro__ (it doesn't have any
580        # __mro__), so no segfault occurs.  Instead it got:
581        #    test_callback_in_cycle_2 (__main__.ReferencesTestCase) ...
582        #    Exception exceptions.AttributeError:
583        #   "II instance has no attribute 'J'" in <bound method II.acallback
584        #       of <?.II instance at 0x00B9B4B8>> ignored
585
586        class J(object):
587            pass
588
589        class II:
590            def acallback(self, ignore):
591                self.J
592
593        I = II()
594        I.J = J
595        I.wr = weakref.ref(J, I.acallback)
596
597        del I, J, II
598        gc.collect()
599
600    def test_callback_in_cycle_3(self):
601        import gc
602
603        # This one broke the first patch that fixed the last two.  In this
604        # case, the objects reachable from the callback aren't also reachable
605        # from the object (c1) *triggering* the callback:  you can get to
606        # c1 from c2, but not vice-versa.  The result was that c2's __dict__
607        # got tp_clear'ed by the time the c2.cb callback got invoked.
608
609        class C:
610            def cb(self, ignore):
611                self.me
612                self.c1
613                self.wr
614
615        c1, c2 = C(), C()
616
617        c2.me = c2
618        c2.c1 = c1
619        c2.wr = weakref.ref(c1, c2.cb)
620
621        del c1, c2
622        gc.collect()
623
624    def test_callback_in_cycle_4(self):
625        import gc
626
627        # Like test_callback_in_cycle_3, except c2 and c1 have different
628        # classes.  c2's class (C) isn't reachable from c1 then, so protecting
629        # objects reachable from the dying object (c1) isn't enough to stop
630        # c2's class (C) from getting tp_clear'ed before c2.cb is invoked.
631        # The result was a segfault (C.__mro__ was NULL when the callback
632        # tried to look up self.me).
633
634        class C(object):
635            def cb(self, ignore):
636                self.me
637                self.c1
638                self.wr
639
640        class D:
641            pass
642
643        c1, c2 = D(), C()
644
645        c2.me = c2
646        c2.c1 = c1
647        c2.wr = weakref.ref(c1, c2.cb)
648
649        del c1, c2, C, D
650        gc.collect()
651
652    @support.requires_type_collecting
653    def test_callback_in_cycle_resurrection(self):
654        import gc
655
656        # Do something nasty in a weakref callback:  resurrect objects
657        # from dead cycles.  For this to be attempted, the weakref and
658        # its callback must also be part of the cyclic trash (else the
659        # objects reachable via the callback couldn't be in cyclic trash
660        # to begin with -- the callback would act like an external root).
661        # But gc clears trash weakrefs with callbacks early now, which
662        # disables the callbacks, so the callbacks shouldn't get called
663        # at all (and so nothing actually gets resurrected).
664
665        alist = []
666        class C(object):
667            def __init__(self, value):
668                self.attribute = value
669
670            def acallback(self, ignore):
671                alist.append(self.c)
672
673        c1, c2 = C(1), C(2)
674        c1.c = c2
675        c2.c = c1
676        c1.wr = weakref.ref(c2, c1.acallback)
677        c2.wr = weakref.ref(c1, c2.acallback)
678
679        def C_went_away(ignore):
680            alist.append("C went away")
681        wr = weakref.ref(C, C_went_away)
682
683        del c1, c2, C   # make them all trash
684        self.assertEqual(alist, [])  # del isn't enough to reclaim anything
685
686        gc.collect()
687        # c1.wr and c2.wr were part of the cyclic trash, so should have
688        # been cleared without their callbacks executing.  OTOH, the weakref
689        # to C is bound to a function local (wr), and wasn't trash, so that
690        # callback should have been invoked when C went away.
691        self.assertEqual(alist, ["C went away"])
692        # The remaining weakref should be dead now (its callback ran).
693        self.assertEqual(wr(), None)
694
695        del alist[:]
696        gc.collect()
697        self.assertEqual(alist, [])
698
699    def test_callbacks_on_callback(self):
700        import gc
701
702        # Set up weakref callbacks *on* weakref callbacks.
703        alist = []
704        def safe_callback(ignore):
705            alist.append("safe_callback called")
706
707        class C(object):
708            def cb(self, ignore):
709                alist.append("cb called")
710
711        c, d = C(), C()
712        c.other = d
713        d.other = c
714        callback = c.cb
715        c.wr = weakref.ref(d, callback)     # this won't trigger
716        d.wr = weakref.ref(callback, d.cb)  # ditto
717        external_wr = weakref.ref(callback, safe_callback)  # but this will
718        self.assertIs(external_wr(), callback)
719
720        # The weakrefs attached to c and d should get cleared, so that
721        # C.cb is never called.  But external_wr isn't part of the cyclic
722        # trash, and no cyclic trash is reachable from it, so safe_callback
723        # should get invoked when the bound method object callback (c.cb)
724        # -- which is itself a callback, and also part of the cyclic trash --
725        # gets reclaimed at the end of gc.
726
727        del callback, c, d, C
728        self.assertEqual(alist, [])  # del isn't enough to clean up cycles
729        gc.collect()
730        self.assertEqual(alist, ["safe_callback called"])
731        self.assertEqual(external_wr(), None)
732
733        del alist[:]
734        gc.collect()
735        self.assertEqual(alist, [])
736
737    def test_gc_during_ref_creation(self):
738        self.check_gc_during_creation(weakref.ref)
739
740    def test_gc_during_proxy_creation(self):
741        self.check_gc_during_creation(weakref.proxy)
742
743    def check_gc_during_creation(self, makeref):
744        thresholds = gc.get_threshold()
745        gc.set_threshold(1, 1, 1)
746        gc.collect()
747        class A:
748            pass
749
750        def callback(*args):
751            pass
752
753        referenced = A()
754
755        a = A()
756        a.a = a
757        a.wr = makeref(referenced)
758
759        try:
760            # now make sure the object and the ref get labeled as
761            # cyclic trash:
762            a = A()
763            weakref.ref(referenced, callback)
764
765        finally:
766            gc.set_threshold(*thresholds)
767
768    def test_ref_created_during_del(self):
769        # Bug #1377858
770        # A weakref created in an object's __del__() would crash the
771        # interpreter when the weakref was cleaned up since it would refer to
772        # non-existent memory.  This test should not segfault the interpreter.
773        class Target(object):
774            def __del__(self):
775                global ref_from_del
776                ref_from_del = weakref.ref(self)
777
778        w = Target()
779
780    def test_init(self):
781        # Issue 3634
782        # <weakref to class>.__init__() doesn't check errors correctly
783        r = weakref.ref(Exception)
784        self.assertRaises(TypeError, r.__init__, 0, 0, 0, 0, 0)
785        # No exception should be raised here
786        gc.collect()
787
788    def test_classes(self):
789        # Check that classes are weakrefable.
790        class A(object):
791            pass
792        l = []
793        weakref.ref(int)
794        a = weakref.ref(A, l.append)
795        A = None
796        gc.collect()
797        self.assertEqual(a(), None)
798        self.assertEqual(l, [a])
799
800    def test_equality(self):
801        # Alive weakrefs defer equality testing to their underlying object.
802        x = Object(1)
803        y = Object(1)
804        z = Object(2)
805        a = weakref.ref(x)
806        b = weakref.ref(y)
807        c = weakref.ref(z)
808        d = weakref.ref(x)
809        # Note how we directly test the operators here, to stress both
810        # __eq__ and __ne__.
811        self.assertTrue(a == b)
812        self.assertFalse(a != b)
813        self.assertFalse(a == c)
814        self.assertTrue(a != c)
815        self.assertTrue(a == d)
816        self.assertFalse(a != d)
817        del x, y, z
818        gc.collect()
819        for r in a, b, c:
820            # Sanity check
821            self.assertIs(r(), None)
822        # Dead weakrefs compare by identity: whether `a` and `d` are the
823        # same weakref object is an implementation detail, since they pointed
824        # to the same original object and didn't have a callback.
825        # (see issue #16453).
826        self.assertFalse(a == b)
827        self.assertTrue(a != b)
828        self.assertFalse(a == c)
829        self.assertTrue(a != c)
830        self.assertEqual(a == d, a is d)
831        self.assertEqual(a != d, a is not d)
832
833    def test_ordering(self):
834        # weakrefs cannot be ordered, even if the underlying objects can.
835        ops = [operator.lt, operator.gt, operator.le, operator.ge]
836        x = Object(1)
837        y = Object(1)
838        a = weakref.ref(x)
839        b = weakref.ref(y)
840        for op in ops:
841            self.assertRaises(TypeError, op, a, b)
842        # Same when dead.
843        del x, y
844        gc.collect()
845        for op in ops:
846            self.assertRaises(TypeError, op, a, b)
847
848    def test_hashing(self):
849        # Alive weakrefs hash the same as the underlying object
850        x = Object(42)
851        y = Object(42)
852        a = weakref.ref(x)
853        b = weakref.ref(y)
854        self.assertEqual(hash(a), hash(42))
855        del x, y
856        gc.collect()
857        # Dead weakrefs:
858        # - retain their hash is they were hashed when alive;
859        # - otherwise, cannot be hashed.
860        self.assertEqual(hash(a), hash(42))
861        self.assertRaises(TypeError, hash, b)
862
863    def test_trashcan_16602(self):
864        # Issue #16602: when a weakref's target was part of a long
865        # deallocation chain, the trashcan mechanism could delay clearing
866        # of the weakref and make the target object visible from outside
867        # code even though its refcount had dropped to 0.  A crash ensued.
868        class C:
869            def __init__(self, parent):
870                if not parent:
871                    return
872                wself = weakref.ref(self)
873                def cb(wparent):
874                    o = wself()
875                self.wparent = weakref.ref(parent, cb)
876
877        d = weakref.WeakKeyDictionary()
878        root = c = C(None)
879        for n in range(100):
880            d[c] = c = C(c)
881        del root
882        gc.collect()
883
884    def test_callback_attribute(self):
885        x = Object(1)
886        callback = lambda ref: None
887        ref1 = weakref.ref(x, callback)
888        self.assertIs(ref1.__callback__, callback)
889
890        ref2 = weakref.ref(x)
891        self.assertIsNone(ref2.__callback__)
892
893    def test_callback_attribute_after_deletion(self):
894        x = Object(1)
895        ref = weakref.ref(x, self.callback)
896        self.assertIsNotNone(ref.__callback__)
897        del x
898        support.gc_collect()
899        self.assertIsNone(ref.__callback__)
900
901    def test_set_callback_attribute(self):
902        x = Object(1)
903        callback = lambda ref: None
904        ref1 = weakref.ref(x, callback)
905        with self.assertRaises(AttributeError):
906            ref1.__callback__ = lambda ref: None
907
908    def test_callback_gcs(self):
909        class ObjectWithDel(Object):
910            def __del__(self): pass
911        x = ObjectWithDel(1)
912        ref1 = weakref.ref(x, lambda ref: support.gc_collect())
913        del x
914        support.gc_collect()
915
916
917class SubclassableWeakrefTestCase(TestBase):
918
919    def test_subclass_refs(self):
920        class MyRef(weakref.ref):
921            def __init__(self, ob, callback=None, value=42):
922                self.value = value
923                super().__init__(ob, callback)
924            def __call__(self):
925                self.called = True
926                return super().__call__()
927        o = Object("foo")
928        mr = MyRef(o, value=24)
929        self.assertIs(mr(), o)
930        self.assertTrue(mr.called)
931        self.assertEqual(mr.value, 24)
932        del o
933        self.assertIsNone(mr())
934        self.assertTrue(mr.called)
935
936    def test_subclass_refs_dont_replace_standard_refs(self):
937        class MyRef(weakref.ref):
938            pass
939        o = Object(42)
940        r1 = MyRef(o)
941        r2 = weakref.ref(o)
942        self.assertIsNot(r1, r2)
943        self.assertEqual(weakref.getweakrefs(o), [r2, r1])
944        self.assertEqual(weakref.getweakrefcount(o), 2)
945        r3 = MyRef(o)
946        self.assertEqual(weakref.getweakrefcount(o), 3)
947        refs = weakref.getweakrefs(o)
948        self.assertEqual(len(refs), 3)
949        self.assertIs(r2, refs[0])
950        self.assertIn(r1, refs[1:])
951        self.assertIn(r3, refs[1:])
952
953    def test_subclass_refs_dont_conflate_callbacks(self):
954        class MyRef(weakref.ref):
955            pass
956        o = Object(42)
957        r1 = MyRef(o, id)
958        r2 = MyRef(o, str)
959        self.assertIsNot(r1, r2)
960        refs = weakref.getweakrefs(o)
961        self.assertIn(r1, refs)
962        self.assertIn(r2, refs)
963
964    def test_subclass_refs_with_slots(self):
965        class MyRef(weakref.ref):
966            __slots__ = "slot1", "slot2"
967            def __new__(type, ob, callback, slot1, slot2):
968                return weakref.ref.__new__(type, ob, callback)
969            def __init__(self, ob, callback, slot1, slot2):
970                self.slot1 = slot1
971                self.slot2 = slot2
972            def meth(self):
973                return self.slot1 + self.slot2
974        o = Object(42)
975        r = MyRef(o, None, "abc", "def")
976        self.assertEqual(r.slot1, "abc")
977        self.assertEqual(r.slot2, "def")
978        self.assertEqual(r.meth(), "abcdef")
979        self.assertFalse(hasattr(r, "__dict__"))
980
981    def test_subclass_refs_with_cycle(self):
982        """Confirm https://bugs.python.org/issue3100 is fixed."""
983        # An instance of a weakref subclass can have attributes.
984        # If such a weakref holds the only strong reference to the object,
985        # deleting the weakref will delete the object. In this case,
986        # the callback must not be called, because the ref object is
987        # being deleted.
988        class MyRef(weakref.ref):
989            pass
990
991        # Use a local callback, for "regrtest -R::"
992        # to detect refcounting problems
993        def callback(w):
994            self.cbcalled += 1
995
996        o = C()
997        r1 = MyRef(o, callback)
998        r1.o = o
999        del o
1000
1001        del r1 # Used to crash here
1002
1003        self.assertEqual(self.cbcalled, 0)
1004
1005        # Same test, with two weakrefs to the same object
1006        # (since code paths are different)
1007        o = C()
1008        r1 = MyRef(o, callback)
1009        r2 = MyRef(o, callback)
1010        r1.r = r2
1011        r2.o = o
1012        del o
1013        del r2
1014
1015        del r1 # Used to crash here
1016
1017        self.assertEqual(self.cbcalled, 0)
1018
1019
1020class WeakMethodTestCase(unittest.TestCase):
1021
1022    def _subclass(self):
1023        """Return an Object subclass overriding `some_method`."""
1024        class C(Object):
1025            def some_method(self):
1026                return 6
1027        return C
1028
1029    def test_alive(self):
1030        o = Object(1)
1031        r = weakref.WeakMethod(o.some_method)
1032        self.assertIsInstance(r, weakref.ReferenceType)
1033        self.assertIsInstance(r(), type(o.some_method))
1034        self.assertIs(r().__self__, o)
1035        self.assertIs(r().__func__, o.some_method.__func__)
1036        self.assertEqual(r()(), 4)
1037
1038    def test_object_dead(self):
1039        o = Object(1)
1040        r = weakref.WeakMethod(o.some_method)
1041        del o
1042        gc.collect()
1043        self.assertIs(r(), None)
1044
1045    def test_method_dead(self):
1046        C = self._subclass()
1047        o = C(1)
1048        r = weakref.WeakMethod(o.some_method)
1049        del C.some_method
1050        gc.collect()
1051        self.assertIs(r(), None)
1052
1053    def test_callback_when_object_dead(self):
1054        # Test callback behaviour when object dies first.
1055        C = self._subclass()
1056        calls = []
1057        def cb(arg):
1058            calls.append(arg)
1059        o = C(1)
1060        r = weakref.WeakMethod(o.some_method, cb)
1061        del o
1062        gc.collect()
1063        self.assertEqual(calls, [r])
1064        # Callback is only called once.
1065        C.some_method = Object.some_method
1066        gc.collect()
1067        self.assertEqual(calls, [r])
1068
1069    def test_callback_when_method_dead(self):
1070        # Test callback behaviour when method dies first.
1071        C = self._subclass()
1072        calls = []
1073        def cb(arg):
1074            calls.append(arg)
1075        o = C(1)
1076        r = weakref.WeakMethod(o.some_method, cb)
1077        del C.some_method
1078        gc.collect()
1079        self.assertEqual(calls, [r])
1080        # Callback is only called once.
1081        del o
1082        gc.collect()
1083        self.assertEqual(calls, [r])
1084
1085    @support.cpython_only
1086    def test_no_cycles(self):
1087        # A WeakMethod doesn't create any reference cycle to itself.
1088        o = Object(1)
1089        def cb(_):
1090            pass
1091        r = weakref.WeakMethod(o.some_method, cb)
1092        wr = weakref.ref(r)
1093        del r
1094        self.assertIs(wr(), None)
1095
1096    def test_equality(self):
1097        def _eq(a, b):
1098            self.assertTrue(a == b)
1099            self.assertFalse(a != b)
1100        def _ne(a, b):
1101            self.assertTrue(a != b)
1102            self.assertFalse(a == b)
1103        x = Object(1)
1104        y = Object(1)
1105        a = weakref.WeakMethod(x.some_method)
1106        b = weakref.WeakMethod(y.some_method)
1107        c = weakref.WeakMethod(x.other_method)
1108        d = weakref.WeakMethod(y.other_method)
1109        # Objects equal, same method
1110        _eq(a, b)
1111        _eq(c, d)
1112        # Objects equal, different method
1113        _ne(a, c)
1114        _ne(a, d)
1115        _ne(b, c)
1116        _ne(b, d)
1117        # Objects unequal, same or different method
1118        z = Object(2)
1119        e = weakref.WeakMethod(z.some_method)
1120        f = weakref.WeakMethod(z.other_method)
1121        _ne(a, e)
1122        _ne(a, f)
1123        _ne(b, e)
1124        _ne(b, f)
1125        del x, y, z
1126        gc.collect()
1127        # Dead WeakMethods compare by identity
1128        refs = a, b, c, d, e, f
1129        for q in refs:
1130            for r in refs:
1131                self.assertEqual(q == r, q is r)
1132                self.assertEqual(q != r, q is not r)
1133
1134    def test_hashing(self):
1135        # Alive WeakMethods are hashable if the underlying object is
1136        # hashable.
1137        x = Object(1)
1138        y = Object(1)
1139        a = weakref.WeakMethod(x.some_method)
1140        b = weakref.WeakMethod(y.some_method)
1141        c = weakref.WeakMethod(y.other_method)
1142        # Since WeakMethod objects are equal, the hashes should be equal.
1143        self.assertEqual(hash(a), hash(b))
1144        ha = hash(a)
1145        # Dead WeakMethods retain their old hash value
1146        del x, y
1147        gc.collect()
1148        self.assertEqual(hash(a), ha)
1149        self.assertEqual(hash(b), ha)
1150        # If it wasn't hashed when alive, a dead WeakMethod cannot be hashed.
1151        self.assertRaises(TypeError, hash, c)
1152
1153
1154class MappingTestCase(TestBase):
1155
1156    COUNT = 10
1157
1158    def check_len_cycles(self, dict_type, cons):
1159        N = 20
1160        items = [RefCycle() for i in range(N)]
1161        dct = dict_type(cons(o) for o in items)
1162        # Keep an iterator alive
1163        it = dct.items()
1164        try:
1165            next(it)
1166        except StopIteration:
1167            pass
1168        del items
1169        gc.collect()
1170        n1 = len(dct)
1171        del it
1172        gc.collect()
1173        n2 = len(dct)
1174        # one item may be kept alive inside the iterator
1175        self.assertIn(n1, (0, 1))
1176        self.assertEqual(n2, 0)
1177
1178    def test_weak_keyed_len_cycles(self):
1179        self.check_len_cycles(weakref.WeakKeyDictionary, lambda k: (k, 1))
1180
1181    def test_weak_valued_len_cycles(self):
1182        self.check_len_cycles(weakref.WeakValueDictionary, lambda k: (1, k))
1183
1184    def check_len_race(self, dict_type, cons):
1185        # Extended sanity checks for len() in the face of cyclic collection
1186        self.addCleanup(gc.set_threshold, *gc.get_threshold())
1187        for th in range(1, 100):
1188            N = 20
1189            gc.collect(0)
1190            gc.set_threshold(th, th, th)
1191            items = [RefCycle() for i in range(N)]
1192            dct = dict_type(cons(o) for o in items)
1193            del items
1194            # All items will be collected at next garbage collection pass
1195            it = dct.items()
1196            try:
1197                next(it)
1198            except StopIteration:
1199                pass
1200            n1 = len(dct)
1201            del it
1202            n2 = len(dct)
1203            self.assertGreaterEqual(n1, 0)
1204            self.assertLessEqual(n1, N)
1205            self.assertGreaterEqual(n2, 0)
1206            self.assertLessEqual(n2, n1)
1207
1208    def test_weak_keyed_len_race(self):
1209        self.check_len_race(weakref.WeakKeyDictionary, lambda k: (k, 1))
1210
1211    def test_weak_valued_len_race(self):
1212        self.check_len_race(weakref.WeakValueDictionary, lambda k: (1, k))
1213
1214    def test_weak_values(self):
1215        #
1216        #  This exercises d.copy(), d.items(), d[], del d[], len(d).
1217        #
1218        dict, objects = self.make_weak_valued_dict()
1219        for o in objects:
1220            self.assertEqual(weakref.getweakrefcount(o), 1)
1221            self.assertIs(o, dict[o.arg],
1222                         "wrong object returned by weak dict!")
1223        items1 = list(dict.items())
1224        items2 = list(dict.copy().items())
1225        items1.sort()
1226        items2.sort()
1227        self.assertEqual(items1, items2,
1228                     "cloning of weak-valued dictionary did not work!")
1229        del items1, items2
1230        self.assertEqual(len(dict), self.COUNT)
1231        del objects[0]
1232        self.assertEqual(len(dict), self.COUNT - 1,
1233                     "deleting object did not cause dictionary update")
1234        del objects, o
1235        self.assertEqual(len(dict), 0,
1236                     "deleting the values did not clear the dictionary")
1237        # regression on SF bug #447152:
1238        dict = weakref.WeakValueDictionary()
1239        self.assertRaises(KeyError, dict.__getitem__, 1)
1240        dict[2] = C()
1241        self.assertRaises(KeyError, dict.__getitem__, 2)
1242
1243    def test_weak_keys(self):
1244        #
1245        #  This exercises d.copy(), d.items(), d[] = v, d[], del d[],
1246        #  len(d), k in d.
1247        #
1248        dict, objects = self.make_weak_keyed_dict()
1249        for o in objects:
1250            self.assertEqual(weakref.getweakrefcount(o), 1,
1251                         "wrong number of weak references to %r!" % o)
1252            self.assertIs(o.arg, dict[o],
1253                         "wrong object returned by weak dict!")
1254        items1 = dict.items()
1255        items2 = dict.copy().items()
1256        self.assertEqual(set(items1), set(items2),
1257                     "cloning of weak-keyed dictionary did not work!")
1258        del items1, items2
1259        self.assertEqual(len(dict), self.COUNT)
1260        del objects[0]
1261        self.assertEqual(len(dict), (self.COUNT - 1),
1262                     "deleting object did not cause dictionary update")
1263        del objects, o
1264        self.assertEqual(len(dict), 0,
1265                     "deleting the keys did not clear the dictionary")
1266        o = Object(42)
1267        dict[o] = "What is the meaning of the universe?"
1268        self.assertIn(o, dict)
1269        self.assertNotIn(34, dict)
1270
1271    def test_weak_keyed_iters(self):
1272        dict, objects = self.make_weak_keyed_dict()
1273        self.check_iters(dict)
1274
1275        # Test keyrefs()
1276        refs = dict.keyrefs()
1277        self.assertEqual(len(refs), len(objects))
1278        objects2 = list(objects)
1279        for wr in refs:
1280            ob = wr()
1281            self.assertIn(ob, dict)
1282            self.assertIn(ob, dict)
1283            self.assertEqual(ob.arg, dict[ob])
1284            objects2.remove(ob)
1285        self.assertEqual(len(objects2), 0)
1286
1287        # Test iterkeyrefs()
1288        objects2 = list(objects)
1289        self.assertEqual(len(list(dict.keyrefs())), len(objects))
1290        for wr in dict.keyrefs():
1291            ob = wr()
1292            self.assertIn(ob, dict)
1293            self.assertIn(ob, dict)
1294            self.assertEqual(ob.arg, dict[ob])
1295            objects2.remove(ob)
1296        self.assertEqual(len(objects2), 0)
1297
1298    def test_weak_valued_iters(self):
1299        dict, objects = self.make_weak_valued_dict()
1300        self.check_iters(dict)
1301
1302        # Test valuerefs()
1303        refs = dict.valuerefs()
1304        self.assertEqual(len(refs), len(objects))
1305        objects2 = list(objects)
1306        for wr in refs:
1307            ob = wr()
1308            self.assertEqual(ob, dict[ob.arg])
1309            self.assertEqual(ob.arg, dict[ob.arg].arg)
1310            objects2.remove(ob)
1311        self.assertEqual(len(objects2), 0)
1312
1313        # Test itervaluerefs()
1314        objects2 = list(objects)
1315        self.assertEqual(len(list(dict.itervaluerefs())), len(objects))
1316        for wr in dict.itervaluerefs():
1317            ob = wr()
1318            self.assertEqual(ob, dict[ob.arg])
1319            self.assertEqual(ob.arg, dict[ob.arg].arg)
1320            objects2.remove(ob)
1321        self.assertEqual(len(objects2), 0)
1322
1323    def check_iters(self, dict):
1324        # item iterator:
1325        items = list(dict.items())
1326        for item in dict.items():
1327            items.remove(item)
1328        self.assertFalse(items, "items() did not touch all items")
1329
1330        # key iterator, via __iter__():
1331        keys = list(dict.keys())
1332        for k in dict:
1333            keys.remove(k)
1334        self.assertFalse(keys, "__iter__() did not touch all keys")
1335
1336        # key iterator, via iterkeys():
1337        keys = list(dict.keys())
1338        for k in dict.keys():
1339            keys.remove(k)
1340        self.assertFalse(keys, "iterkeys() did not touch all keys")
1341
1342        # value iterator:
1343        values = list(dict.values())
1344        for v in dict.values():
1345            values.remove(v)
1346        self.assertFalse(values,
1347                     "itervalues() did not touch all values")
1348
1349    def check_weak_destroy_while_iterating(self, dict, objects, iter_name):
1350        n = len(dict)
1351        it = iter(getattr(dict, iter_name)())
1352        next(it)             # Trigger internal iteration
1353        # Destroy an object
1354        del objects[-1]
1355        gc.collect()    # just in case
1356        # We have removed either the first consumed object, or another one
1357        self.assertIn(len(list(it)), [len(objects), len(objects) - 1])
1358        del it
1359        # The removal has been committed
1360        self.assertEqual(len(dict), n - 1)
1361
1362    def check_weak_destroy_and_mutate_while_iterating(self, dict, testcontext):
1363        # Check that we can explicitly mutate the weak dict without
1364        # interfering with delayed removal.
1365        # `testcontext` should create an iterator, destroy one of the
1366        # weakref'ed objects and then return a new key/value pair corresponding
1367        # to the destroyed object.
1368        with testcontext() as (k, v):
1369            self.assertNotIn(k, dict)
1370        with testcontext() as (k, v):
1371            self.assertRaises(KeyError, dict.__delitem__, k)
1372        self.assertNotIn(k, dict)
1373        with testcontext() as (k, v):
1374            self.assertRaises(KeyError, dict.pop, k)
1375        self.assertNotIn(k, dict)
1376        with testcontext() as (k, v):
1377            dict[k] = v
1378        self.assertEqual(dict[k], v)
1379        ddict = copy.copy(dict)
1380        with testcontext() as (k, v):
1381            dict.update(ddict)
1382        self.assertEqual(dict, ddict)
1383        with testcontext() as (k, v):
1384            dict.clear()
1385        self.assertEqual(len(dict), 0)
1386
1387    def check_weak_del_and_len_while_iterating(self, dict, testcontext):
1388        # Check that len() works when both iterating and removing keys
1389        # explicitly through various means (.pop(), .clear()...), while
1390        # implicit mutation is deferred because an iterator is alive.
1391        # (each call to testcontext() should schedule one item for removal
1392        #  for this test to work properly)
1393        o = Object(123456)
1394        with testcontext():
1395            n = len(dict)
1396            # Since underlaying dict is ordered, first item is popped
1397            dict.pop(next(dict.keys()))
1398            self.assertEqual(len(dict), n - 1)
1399            dict[o] = o
1400            self.assertEqual(len(dict), n)
1401        # last item in objects is removed from dict in context shutdown
1402        with testcontext():
1403            self.assertEqual(len(dict), n - 1)
1404            # Then, (o, o) is popped
1405            dict.popitem()
1406            self.assertEqual(len(dict), n - 2)
1407        with testcontext():
1408            self.assertEqual(len(dict), n - 3)
1409            del dict[next(dict.keys())]
1410            self.assertEqual(len(dict), n - 4)
1411        with testcontext():
1412            self.assertEqual(len(dict), n - 5)
1413            dict.popitem()
1414            self.assertEqual(len(dict), n - 6)
1415        with testcontext():
1416            dict.clear()
1417            self.assertEqual(len(dict), 0)
1418        self.assertEqual(len(dict), 0)
1419
1420    def test_weak_keys_destroy_while_iterating(self):
1421        # Issue #7105: iterators shouldn't crash when a key is implicitly removed
1422        dict, objects = self.make_weak_keyed_dict()
1423        self.check_weak_destroy_while_iterating(dict, objects, 'keys')
1424        self.check_weak_destroy_while_iterating(dict, objects, 'items')
1425        self.check_weak_destroy_while_iterating(dict, objects, 'values')
1426        self.check_weak_destroy_while_iterating(dict, objects, 'keyrefs')
1427        dict, objects = self.make_weak_keyed_dict()
1428        @contextlib.contextmanager
1429        def testcontext():
1430            try:
1431                it = iter(dict.items())
1432                next(it)
1433                # Schedule a key/value for removal and recreate it
1434                v = objects.pop().arg
1435                gc.collect()      # just in case
1436                yield Object(v), v
1437            finally:
1438                it = None           # should commit all removals
1439                gc.collect()
1440        self.check_weak_destroy_and_mutate_while_iterating(dict, testcontext)
1441        # Issue #21173: len() fragile when keys are both implicitly and
1442        # explicitly removed.
1443        dict, objects = self.make_weak_keyed_dict()
1444        self.check_weak_del_and_len_while_iterating(dict, testcontext)
1445
1446    def test_weak_values_destroy_while_iterating(self):
1447        # Issue #7105: iterators shouldn't crash when a key is implicitly removed
1448        dict, objects = self.make_weak_valued_dict()
1449        self.check_weak_destroy_while_iterating(dict, objects, 'keys')
1450        self.check_weak_destroy_while_iterating(dict, objects, 'items')
1451        self.check_weak_destroy_while_iterating(dict, objects, 'values')
1452        self.check_weak_destroy_while_iterating(dict, objects, 'itervaluerefs')
1453        self.check_weak_destroy_while_iterating(dict, objects, 'valuerefs')
1454        dict, objects = self.make_weak_valued_dict()
1455        @contextlib.contextmanager
1456        def testcontext():
1457            try:
1458                it = iter(dict.items())
1459                next(it)
1460                # Schedule a key/value for removal and recreate it
1461                k = objects.pop().arg
1462                gc.collect()      # just in case
1463                yield k, Object(k)
1464            finally:
1465                it = None           # should commit all removals
1466                gc.collect()
1467        self.check_weak_destroy_and_mutate_while_iterating(dict, testcontext)
1468        dict, objects = self.make_weak_valued_dict()
1469        self.check_weak_del_and_len_while_iterating(dict, testcontext)
1470
1471    def test_make_weak_keyed_dict_from_dict(self):
1472        o = Object(3)
1473        dict = weakref.WeakKeyDictionary({o:364})
1474        self.assertEqual(dict[o], 364)
1475
1476    def test_make_weak_keyed_dict_from_weak_keyed_dict(self):
1477        o = Object(3)
1478        dict = weakref.WeakKeyDictionary({o:364})
1479        dict2 = weakref.WeakKeyDictionary(dict)
1480        self.assertEqual(dict[o], 364)
1481
1482    def make_weak_keyed_dict(self):
1483        dict = weakref.WeakKeyDictionary()
1484        objects = list(map(Object, range(self.COUNT)))
1485        for o in objects:
1486            dict[o] = o.arg
1487        return dict, objects
1488
1489    def test_make_weak_valued_dict_from_dict(self):
1490        o = Object(3)
1491        dict = weakref.WeakValueDictionary({364:o})
1492        self.assertEqual(dict[364], o)
1493
1494    def test_make_weak_valued_dict_from_weak_valued_dict(self):
1495        o = Object(3)
1496        dict = weakref.WeakValueDictionary({364:o})
1497        dict2 = weakref.WeakValueDictionary(dict)
1498        self.assertEqual(dict[364], o)
1499
1500    def test_make_weak_valued_dict_misc(self):
1501        # errors
1502        self.assertRaises(TypeError, weakref.WeakValueDictionary.__init__)
1503        self.assertRaises(TypeError, weakref.WeakValueDictionary, {}, {})
1504        self.assertRaises(TypeError, weakref.WeakValueDictionary, (), ())
1505        # special keyword arguments
1506        o = Object(3)
1507        for kw in 'self', 'dict', 'other', 'iterable':
1508            d = weakref.WeakValueDictionary(**{kw: o})
1509            self.assertEqual(list(d.keys()), [kw])
1510            self.assertEqual(d[kw], o)
1511
1512    def make_weak_valued_dict(self):
1513        dict = weakref.WeakValueDictionary()
1514        objects = list(map(Object, range(self.COUNT)))
1515        for o in objects:
1516            dict[o.arg] = o
1517        return dict, objects
1518
1519    def check_popitem(self, klass, key1, value1, key2, value2):
1520        weakdict = klass()
1521        weakdict[key1] = value1
1522        weakdict[key2] = value2
1523        self.assertEqual(len(weakdict), 2)
1524        k, v = weakdict.popitem()
1525        self.assertEqual(len(weakdict), 1)
1526        if k is key1:
1527            self.assertIs(v, value1)
1528        else:
1529            self.assertIs(v, value2)
1530        k, v = weakdict.popitem()
1531        self.assertEqual(len(weakdict), 0)
1532        if k is key1:
1533            self.assertIs(v, value1)
1534        else:
1535            self.assertIs(v, value2)
1536
1537    def test_weak_valued_dict_popitem(self):
1538        self.check_popitem(weakref.WeakValueDictionary,
1539                           "key1", C(), "key2", C())
1540
1541    def test_weak_keyed_dict_popitem(self):
1542        self.check_popitem(weakref.WeakKeyDictionary,
1543                           C(), "value 1", C(), "value 2")
1544
1545    def check_setdefault(self, klass, key, value1, value2):
1546        self.assertIsNot(value1, value2,
1547                     "invalid test"
1548                     " -- value parameters must be distinct objects")
1549        weakdict = klass()
1550        o = weakdict.setdefault(key, value1)
1551        self.assertIs(o, value1)
1552        self.assertIn(key, weakdict)
1553        self.assertIs(weakdict.get(key), value1)
1554        self.assertIs(weakdict[key], value1)
1555
1556        o = weakdict.setdefault(key, value2)
1557        self.assertIs(o, value1)
1558        self.assertIn(key, weakdict)
1559        self.assertIs(weakdict.get(key), value1)
1560        self.assertIs(weakdict[key], value1)
1561
1562    def test_weak_valued_dict_setdefault(self):
1563        self.check_setdefault(weakref.WeakValueDictionary,
1564                              "key", C(), C())
1565
1566    def test_weak_keyed_dict_setdefault(self):
1567        self.check_setdefault(weakref.WeakKeyDictionary,
1568                              C(), "value 1", "value 2")
1569
1570    def check_update(self, klass, dict):
1571        #
1572        #  This exercises d.update(), len(d), d.keys(), k in d,
1573        #  d.get(), d[].
1574        #
1575        weakdict = klass()
1576        weakdict.update(dict)
1577        self.assertEqual(len(weakdict), len(dict))
1578        for k in weakdict.keys():
1579            self.assertIn(k, dict, "mysterious new key appeared in weak dict")
1580            v = dict.get(k)
1581            self.assertIs(v, weakdict[k])
1582            self.assertIs(v, weakdict.get(k))
1583        for k in dict.keys():
1584            self.assertIn(k, weakdict, "original key disappeared in weak dict")
1585            v = dict[k]
1586            self.assertIs(v, weakdict[k])
1587            self.assertIs(v, weakdict.get(k))
1588
1589    def test_weak_valued_dict_update(self):
1590        self.check_update(weakref.WeakValueDictionary,
1591                          {1: C(), 'a': C(), C(): C()})
1592        # errors
1593        self.assertRaises(TypeError, weakref.WeakValueDictionary.update)
1594        d = weakref.WeakValueDictionary()
1595        self.assertRaises(TypeError, d.update, {}, {})
1596        self.assertRaises(TypeError, d.update, (), ())
1597        self.assertEqual(list(d.keys()), [])
1598        # special keyword arguments
1599        o = Object(3)
1600        for kw in 'self', 'dict', 'other', 'iterable':
1601            d = weakref.WeakValueDictionary()
1602            d.update(**{kw: o})
1603            self.assertEqual(list(d.keys()), [kw])
1604            self.assertEqual(d[kw], o)
1605
1606    def test_weak_keyed_dict_update(self):
1607        self.check_update(weakref.WeakKeyDictionary,
1608                          {C(): 1, C(): 2, C(): 3})
1609
1610    def test_weak_keyed_delitem(self):
1611        d = weakref.WeakKeyDictionary()
1612        o1 = Object('1')
1613        o2 = Object('2')
1614        d[o1] = 'something'
1615        d[o2] = 'something'
1616        self.assertEqual(len(d), 2)
1617        del d[o1]
1618        self.assertEqual(len(d), 1)
1619        self.assertEqual(list(d.keys()), [o2])
1620
1621    def test_weak_valued_delitem(self):
1622        d = weakref.WeakValueDictionary()
1623        o1 = Object('1')
1624        o2 = Object('2')
1625        d['something'] = o1
1626        d['something else'] = o2
1627        self.assertEqual(len(d), 2)
1628        del d['something']
1629        self.assertEqual(len(d), 1)
1630        self.assertEqual(list(d.items()), [('something else', o2)])
1631
1632    def test_weak_keyed_bad_delitem(self):
1633        d = weakref.WeakKeyDictionary()
1634        o = Object('1')
1635        # An attempt to delete an object that isn't there should raise
1636        # KeyError.  It didn't before 2.3.
1637        self.assertRaises(KeyError, d.__delitem__, o)
1638        self.assertRaises(KeyError, d.__getitem__, o)
1639
1640        # If a key isn't of a weakly referencable type, __getitem__ and
1641        # __setitem__ raise TypeError.  __delitem__ should too.
1642        self.assertRaises(TypeError, d.__delitem__,  13)
1643        self.assertRaises(TypeError, d.__getitem__,  13)
1644        self.assertRaises(TypeError, d.__setitem__,  13, 13)
1645
1646    def test_weak_keyed_cascading_deletes(self):
1647        # SF bug 742860.  For some reason, before 2.3 __delitem__ iterated
1648        # over the keys via self.data.iterkeys().  If things vanished from
1649        # the dict during this (or got added), that caused a RuntimeError.
1650
1651        d = weakref.WeakKeyDictionary()
1652        mutate = False
1653
1654        class C(object):
1655            def __init__(self, i):
1656                self.value = i
1657            def __hash__(self):
1658                return hash(self.value)
1659            def __eq__(self, other):
1660                if mutate:
1661                    # Side effect that mutates the dict, by removing the
1662                    # last strong reference to a key.
1663                    del objs[-1]
1664                return self.value == other.value
1665
1666        objs = [C(i) for i in range(4)]
1667        for o in objs:
1668            d[o] = o.value
1669        del o   # now the only strong references to keys are in objs
1670        # Find the order in which iterkeys sees the keys.
1671        objs = list(d.keys())
1672        # Reverse it, so that the iteration implementation of __delitem__
1673        # has to keep looping to find the first object we delete.
1674        objs.reverse()
1675
1676        # Turn on mutation in C.__eq__.  The first time through the loop,
1677        # under the iterkeys() business the first comparison will delete
1678        # the last item iterkeys() would see, and that causes a
1679        #     RuntimeError: dictionary changed size during iteration
1680        # when the iterkeys() loop goes around to try comparing the next
1681        # key.  After this was fixed, it just deletes the last object *our*
1682        # "for o in obj" loop would have gotten to.
1683        mutate = True
1684        count = 0
1685        for o in objs:
1686            count += 1
1687            del d[o]
1688        self.assertEqual(len(d), 0)
1689        self.assertEqual(count, 2)
1690
1691    def test_make_weak_valued_dict_repr(self):
1692        dict = weakref.WeakValueDictionary()
1693        self.assertRegex(repr(dict), '<WeakValueDictionary at 0x.*>')
1694
1695    def test_make_weak_keyed_dict_repr(self):
1696        dict = weakref.WeakKeyDictionary()
1697        self.assertRegex(repr(dict), '<WeakKeyDictionary at 0x.*>')
1698
1699    def test_threaded_weak_valued_setdefault(self):
1700        d = weakref.WeakValueDictionary()
1701        with collect_in_thread():
1702            for i in range(100000):
1703                x = d.setdefault(10, RefCycle())
1704                self.assertIsNot(x, None)  # we never put None in there!
1705                del x
1706
1707    def test_threaded_weak_valued_pop(self):
1708        d = weakref.WeakValueDictionary()
1709        with collect_in_thread():
1710            for i in range(100000):
1711                d[10] = RefCycle()
1712                x = d.pop(10, 10)
1713                self.assertIsNot(x, None)  # we never put None in there!
1714
1715    def test_threaded_weak_valued_consistency(self):
1716        # Issue #28427: old keys should not remove new values from
1717        # WeakValueDictionary when collecting from another thread.
1718        d = weakref.WeakValueDictionary()
1719        with collect_in_thread():
1720            for i in range(200000):
1721                o = RefCycle()
1722                d[10] = o
1723                # o is still alive, so the dict can't be empty
1724                self.assertEqual(len(d), 1)
1725                o = None  # lose ref
1726
1727    def check_threaded_weak_dict_copy(self, type_, deepcopy):
1728        # `type_` should be either WeakKeyDictionary or WeakValueDictionary.
1729        # `deepcopy` should be either True or False.
1730        exc = []
1731
1732        class DummyKey:
1733            def __init__(self, ctr):
1734                self.ctr = ctr
1735
1736        class DummyValue:
1737            def __init__(self, ctr):
1738                self.ctr = ctr
1739
1740        def dict_copy(d, exc):
1741            try:
1742                if deepcopy is True:
1743                    _ = copy.deepcopy(d)
1744                else:
1745                    _ = d.copy()
1746            except Exception as ex:
1747                exc.append(ex)
1748
1749        def pop_and_collect(lst):
1750            gc_ctr = 0
1751            while lst:
1752                i = random.randint(0, len(lst) - 1)
1753                gc_ctr += 1
1754                lst.pop(i)
1755                if gc_ctr % 10000 == 0:
1756                    gc.collect()  # just in case
1757
1758        self.assertIn(type_, (weakref.WeakKeyDictionary, weakref.WeakValueDictionary))
1759
1760        d = type_()
1761        keys = []
1762        values = []
1763        # Initialize d with many entries
1764        for i in range(70000):
1765            k, v = DummyKey(i), DummyValue(i)
1766            keys.append(k)
1767            values.append(v)
1768            d[k] = v
1769            del k
1770            del v
1771
1772        t_copy = threading.Thread(target=dict_copy, args=(d, exc,))
1773        if type_ is weakref.WeakKeyDictionary:
1774            t_collect = threading.Thread(target=pop_and_collect, args=(keys,))
1775        else:  # weakref.WeakValueDictionary
1776            t_collect = threading.Thread(target=pop_and_collect, args=(values,))
1777
1778        t_copy.start()
1779        t_collect.start()
1780
1781        t_copy.join()
1782        t_collect.join()
1783
1784        # Test exceptions
1785        if exc:
1786            raise exc[0]
1787
1788    def test_threaded_weak_key_dict_copy(self):
1789        # Issue #35615: Weakref keys or values getting GC'ed during dict
1790        # copying should not result in a crash.
1791        self.check_threaded_weak_dict_copy(weakref.WeakKeyDictionary, False)
1792
1793    def test_threaded_weak_key_dict_deepcopy(self):
1794        # Issue #35615: Weakref keys or values getting GC'ed during dict
1795        # copying should not result in a crash.
1796        self.check_threaded_weak_dict_copy(weakref.WeakKeyDictionary, True)
1797
1798    def test_threaded_weak_value_dict_copy(self):
1799        # Issue #35615: Weakref keys or values getting GC'ed during dict
1800        # copying should not result in a crash.
1801        self.check_threaded_weak_dict_copy(weakref.WeakValueDictionary, False)
1802
1803    def test_threaded_weak_value_dict_deepcopy(self):
1804        # Issue #35615: Weakref keys or values getting GC'ed during dict
1805        # copying should not result in a crash.
1806        self.check_threaded_weak_dict_copy(weakref.WeakValueDictionary, True)
1807
1808    @support.cpython_only
1809    def test_remove_closure(self):
1810        d = weakref.WeakValueDictionary()
1811        self.assertIsNone(d._remove.__closure__)
1812
1813
1814from test import mapping_tests
1815
1816class WeakValueDictionaryTestCase(mapping_tests.BasicTestMappingProtocol):
1817    """Check that WeakValueDictionary conforms to the mapping protocol"""
1818    __ref = {"key1":Object(1), "key2":Object(2), "key3":Object(3)}
1819    type2test = weakref.WeakValueDictionary
1820    def _reference(self):
1821        return self.__ref.copy()
1822
1823class WeakKeyDictionaryTestCase(mapping_tests.BasicTestMappingProtocol):
1824    """Check that WeakKeyDictionary conforms to the mapping protocol"""
1825    __ref = {Object("key1"):1, Object("key2"):2, Object("key3"):3}
1826    type2test = weakref.WeakKeyDictionary
1827    def _reference(self):
1828        return self.__ref.copy()
1829
1830
1831class FinalizeTestCase(unittest.TestCase):
1832
1833    class A:
1834        pass
1835
1836    def _collect_if_necessary(self):
1837        # we create no ref-cycles so in CPython no gc should be needed
1838        if sys.implementation.name != 'cpython':
1839            support.gc_collect()
1840
1841    def test_finalize(self):
1842        def add(x,y,z):
1843            res.append(x + y + z)
1844            return x + y + z
1845
1846        a = self.A()
1847
1848        res = []
1849        f = weakref.finalize(a, add, 67, 43, z=89)
1850        self.assertEqual(f.alive, True)
1851        self.assertEqual(f.peek(), (a, add, (67,43), {'z':89}))
1852        self.assertEqual(f(), 199)
1853        self.assertEqual(f(), None)
1854        self.assertEqual(f(), None)
1855        self.assertEqual(f.peek(), None)
1856        self.assertEqual(f.detach(), None)
1857        self.assertEqual(f.alive, False)
1858        self.assertEqual(res, [199])
1859
1860        res = []
1861        f = weakref.finalize(a, add, 67, 43, 89)
1862        self.assertEqual(f.peek(), (a, add, (67,43,89), {}))
1863        self.assertEqual(f.detach(), (a, add, (67,43,89), {}))
1864        self.assertEqual(f(), None)
1865        self.assertEqual(f(), None)
1866        self.assertEqual(f.peek(), None)
1867        self.assertEqual(f.detach(), None)
1868        self.assertEqual(f.alive, False)
1869        self.assertEqual(res, [])
1870
1871        res = []
1872        f = weakref.finalize(a, add, x=67, y=43, z=89)
1873        del a
1874        self._collect_if_necessary()
1875        self.assertEqual(f(), None)
1876        self.assertEqual(f(), None)
1877        self.assertEqual(f.peek(), None)
1878        self.assertEqual(f.detach(), None)
1879        self.assertEqual(f.alive, False)
1880        self.assertEqual(res, [199])
1881
1882    def test_arg_errors(self):
1883        def fin(*args, **kwargs):
1884            res.append((args, kwargs))
1885
1886        a = self.A()
1887
1888        res = []
1889        f = weakref.finalize(a, fin, 1, 2, func=3, obj=4)
1890        self.assertEqual(f.peek(), (a, fin, (1, 2), {'func': 3, 'obj': 4}))
1891        f()
1892        self.assertEqual(res, [((1, 2), {'func': 3, 'obj': 4})])
1893
1894        res = []
1895        with self.assertWarns(DeprecationWarning):
1896            f = weakref.finalize(a, func=fin, arg=1)
1897        self.assertEqual(f.peek(), (a, fin, (), {'arg': 1}))
1898        f()
1899        self.assertEqual(res, [((), {'arg': 1})])
1900
1901        res = []
1902        with self.assertWarns(DeprecationWarning):
1903            f = weakref.finalize(obj=a, func=fin, arg=1)
1904        self.assertEqual(f.peek(), (a, fin, (), {'arg': 1}))
1905        f()
1906        self.assertEqual(res, [((), {'arg': 1})])
1907
1908        self.assertRaises(TypeError, weakref.finalize, a)
1909        self.assertRaises(TypeError, weakref.finalize)
1910
1911    def test_order(self):
1912        a = self.A()
1913        res = []
1914
1915        f1 = weakref.finalize(a, res.append, 'f1')
1916        f2 = weakref.finalize(a, res.append, 'f2')
1917        f3 = weakref.finalize(a, res.append, 'f3')
1918        f4 = weakref.finalize(a, res.append, 'f4')
1919        f5 = weakref.finalize(a, res.append, 'f5')
1920
1921        # make sure finalizers can keep themselves alive
1922        del f1, f4
1923
1924        self.assertTrue(f2.alive)
1925        self.assertTrue(f3.alive)
1926        self.assertTrue(f5.alive)
1927
1928        self.assertTrue(f5.detach())
1929        self.assertFalse(f5.alive)
1930
1931        f5()                       # nothing because previously unregistered
1932        res.append('A')
1933        f3()                       # => res.append('f3')
1934        self.assertFalse(f3.alive)
1935        res.append('B')
1936        f3()                       # nothing because previously called
1937        res.append('C')
1938        del a
1939        self._collect_if_necessary()
1940                                   # => res.append('f4')
1941                                   # => res.append('f2')
1942                                   # => res.append('f1')
1943        self.assertFalse(f2.alive)
1944        res.append('D')
1945        f2()                       # nothing because previously called by gc
1946
1947        expected = ['A', 'f3', 'B', 'C', 'f4', 'f2', 'f1', 'D']
1948        self.assertEqual(res, expected)
1949
1950    def test_all_freed(self):
1951        # we want a weakrefable subclass of weakref.finalize
1952        class MyFinalizer(weakref.finalize):
1953            pass
1954
1955        a = self.A()
1956        res = []
1957        def callback():
1958            res.append(123)
1959        f = MyFinalizer(a, callback)
1960
1961        wr_callback = weakref.ref(callback)
1962        wr_f = weakref.ref(f)
1963        del callback, f
1964
1965        self.assertIsNotNone(wr_callback())
1966        self.assertIsNotNone(wr_f())
1967
1968        del a
1969        self._collect_if_necessary()
1970
1971        self.assertIsNone(wr_callback())
1972        self.assertIsNone(wr_f())
1973        self.assertEqual(res, [123])
1974
1975    @classmethod
1976    def run_in_child(cls):
1977        def error():
1978            # Create an atexit finalizer from inside a finalizer called
1979            # at exit.  This should be the next to be run.
1980            g1 = weakref.finalize(cls, print, 'g1')
1981            print('f3 error')
1982            1/0
1983
1984        # cls should stay alive till atexit callbacks run
1985        f1 = weakref.finalize(cls, print, 'f1', _global_var)
1986        f2 = weakref.finalize(cls, print, 'f2', _global_var)
1987        f3 = weakref.finalize(cls, error)
1988        f4 = weakref.finalize(cls, print, 'f4', _global_var)
1989
1990        assert f1.atexit == True
1991        f2.atexit = False
1992        assert f3.atexit == True
1993        assert f4.atexit == True
1994
1995    def test_atexit(self):
1996        prog = ('from test.test_weakref import FinalizeTestCase;'+
1997                'FinalizeTestCase.run_in_child()')
1998        rc, out, err = script_helper.assert_python_ok('-c', prog)
1999        out = out.decode('ascii').splitlines()
2000        self.assertEqual(out, ['f4 foobar', 'f3 error', 'g1', 'f1 foobar'])
2001        self.assertTrue(b'ZeroDivisionError' in err)
2002
2003
2004libreftest = """ Doctest for examples in the library reference: weakref.rst
2005
2006>>> import weakref
2007>>> class Dict(dict):
2008...     pass
2009...
2010>>> obj = Dict(red=1, green=2, blue=3)   # this object is weak referencable
2011>>> r = weakref.ref(obj)
2012>>> print(r() is obj)
2013True
2014
2015>>> import weakref
2016>>> class Object:
2017...     pass
2018...
2019>>> o = Object()
2020>>> r = weakref.ref(o)
2021>>> o2 = r()
2022>>> o is o2
2023True
2024>>> del o, o2
2025>>> print(r())
2026None
2027
2028>>> import weakref
2029>>> class ExtendedRef(weakref.ref):
2030...     def __init__(self, ob, callback=None, **annotations):
2031...         super().__init__(ob, callback)
2032...         self.__counter = 0
2033...         for k, v in annotations.items():
2034...             setattr(self, k, v)
2035...     def __call__(self):
2036...         '''Return a pair containing the referent and the number of
2037...         times the reference has been called.
2038...         '''
2039...         ob = super().__call__()
2040...         if ob is not None:
2041...             self.__counter += 1
2042...             ob = (ob, self.__counter)
2043...         return ob
2044...
2045>>> class A:   # not in docs from here, just testing the ExtendedRef
2046...     pass
2047...
2048>>> a = A()
2049>>> r = ExtendedRef(a, foo=1, bar="baz")
2050>>> r.foo
20511
2052>>> r.bar
2053'baz'
2054>>> r()[1]
20551
2056>>> r()[1]
20572
2058>>> r()[0] is a
2059True
2060
2061
2062>>> import weakref
2063>>> _id2obj_dict = weakref.WeakValueDictionary()
2064>>> def remember(obj):
2065...     oid = id(obj)
2066...     _id2obj_dict[oid] = obj
2067...     return oid
2068...
2069>>> def id2obj(oid):
2070...     return _id2obj_dict[oid]
2071...
2072>>> a = A()             # from here, just testing
2073>>> a_id = remember(a)
2074>>> id2obj(a_id) is a
2075True
2076>>> del a
2077>>> try:
2078...     id2obj(a_id)
2079... except KeyError:
2080...     print('OK')
2081... else:
2082...     print('WeakValueDictionary error')
2083OK
2084
2085"""
2086
2087__test__ = {'libreftest' : libreftest}
2088
2089def test_main():
2090    support.run_unittest(
2091        ReferencesTestCase,
2092        WeakMethodTestCase,
2093        MappingTestCase,
2094        WeakValueDictionaryTestCase,
2095        WeakKeyDictionaryTestCase,
2096        SubclassableWeakrefTestCase,
2097        FinalizeTestCase,
2098        )
2099    support.run_doctest(sys.modules[__name__])
2100
2101
2102if __name__ == "__main__":
2103    test_main()
2104