@@ -109,10 +109,21 @@ def test_error(self):
109109 self .watch (wid , d )
110110 with catch_unraisable_exception () as cm :
111111 d ["foo" ] = "bar"
112- self .assertIs (cm .unraisable .object , d )
112+ self .assertIn (
113+ "PyDict_EVENT_ADDED watcher callback for <dict at" ,
114+ cm .unraisable .object
115+ )
113116 self .assertEqual (str (cm .unraisable .exc_value ), "boom!" )
114117 self .assert_events ([])
115118
119+ def test_dealloc_error (self ):
120+ d = {}
121+ with self .watcher (kind = self .ERROR ) as wid :
122+ self .watch (wid , d )
123+ with catch_unraisable_exception () as cm :
124+ del d
125+ self .assertEqual (str (cm .unraisable .exc_value ), "boom!" )
126+
116127 def test_two_watchers (self ):
117128 d1 = {}
118129 d2 = {}
@@ -389,6 +400,25 @@ def test_code_object_events_dispatched(self):
389400 del co4
390401 self .assert_event_counts (0 , 0 , 0 , 0 )
391402
403+ def test_error (self ):
404+ with self .code_watcher (2 ):
405+ with catch_unraisable_exception () as cm :
406+ co = _testcapi .code_newempty ("test_watchers" , "dummy0" , 0 )
407+
408+ self .assertEqual (
409+ cm .unraisable .object ,
410+ f"PY_CODE_EVENT_CREATE watcher callback for { co !r} "
411+ )
412+ self .assertEqual (str (cm .unraisable .exc_value ), "boom!" )
413+
414+ def test_dealloc_error (self ):
415+ co = _testcapi .code_newempty ("test_watchers" , "dummy0" , 0 )
416+ with self .code_watcher (2 ):
417+ with catch_unraisable_exception () as cm :
418+ del co
419+
420+ self .assertEqual (str (cm .unraisable .exc_value ), "boom!" )
421+
392422 def test_clear_out_of_range_watcher_id (self ):
393423 with self .assertRaisesRegex (ValueError , r"Invalid code watcher ID -1" ):
394424 _testcapi .clear_code_watcher (- 1 )
@@ -479,7 +509,25 @@ def watcher(*args):
479509 def myfunc ():
480510 pass
481511
482- self .assertIs (cm .unraisable .object , myfunc )
512+ self .assertEqual (
513+ cm .unraisable .object ,
514+ f"PyFunction_EVENT_CREATE watcher callback for { myfunc !r} "
515+ )
516+
517+ def test_dealloc_watcher_raises_error (self ):
518+ class MyError (Exception ):
519+ pass
520+
521+ def watcher (* args ):
522+ raise MyError ("testing 123" )
523+
524+ def myfunc ():
525+ pass
526+
527+ with self .add_watcher (watcher ):
528+ with catch_unraisable_exception () as cm :
529+ del myfunc
530+
483531 self .assertIsInstance (cm .unraisable .exc_value , MyError )
484532
485533 def test_clear_out_of_range_watcher_id (self ):
0 commit comments