20
20
import weakref
21
21
from test import support
22
22
from test .support import MISSING_C_DOCSTRINGS
23
+ from test .support import catch_unraisable_exception
23
24
from test .support import import_helper
24
25
from test .support import threading_helper
25
26
from test .support import warnings_helper
@@ -1421,6 +1422,9 @@ def assert_events(self, expected):
1421
1422
def watch (self , wid , d ):
1422
1423
_testcapi .watch_dict (wid , d )
1423
1424
1425
+ def unwatch (self , wid , d ):
1426
+ _testcapi .unwatch_dict (wid , d )
1427
+
1424
1428
def test_set_new_item (self ):
1425
1429
d = {}
1426
1430
with self .watcher () as wid :
@@ -1477,27 +1481,24 @@ def test_dealloc(self):
1477
1481
del d
1478
1482
self .assert_events (["dealloc" ])
1479
1483
1484
+ def test_unwatch (self ):
1485
+ d = {}
1486
+ with self .watcher () as wid :
1487
+ self .watch (wid , d )
1488
+ d ["foo" ] = "bar"
1489
+ self .unwatch (wid , d )
1490
+ d ["hmm" ] = "baz"
1491
+ self .assert_events (["new:foo:bar" ])
1492
+
1480
1493
def test_error (self ):
1481
1494
d = {}
1482
- unraisables = []
1483
- def unraisable_hook (unraisable ):
1484
- unraisables .append (unraisable )
1485
1495
with self .watcher (kind = self .ERROR ) as wid :
1486
1496
self .watch (wid , d )
1487
- orig_unraisable_hook = sys .unraisablehook
1488
- sys .unraisablehook = unraisable_hook
1489
- try :
1497
+ with catch_unraisable_exception () as cm :
1490
1498
d ["foo" ] = "bar"
1491
- finally :
1492
- sys . unraisablehook = orig_unraisable_hook
1499
+ self . assertIs ( cm . unraisable . object , d )
1500
+ self . assertEqual ( str ( cm . unraisable . exc_value ), "boom!" )
1493
1501
self .assert_events ([])
1494
- self .assertEqual (len (unraisables ), 1 )
1495
- unraisable = unraisables [0 ]
1496
- self .assertIs (unraisable .object , d )
1497
- self .assertEqual (str (unraisable .exc_value ), "boom!" )
1498
- # avoid leaking reference cycles
1499
- del unraisable
1500
- del unraisables
1501
1502
1502
1503
def test_two_watchers (self ):
1503
1504
d1 = {}
@@ -1522,11 +1523,38 @@ def test_watch_out_of_range_watcher_id(self):
1522
1523
with self .assertRaisesRegex (ValueError , r"Invalid dict watcher ID 8" ):
1523
1524
self .watch (8 , d ) # DICT_MAX_WATCHERS = 8
1524
1525
1525
- def test_unassigned_watcher_id (self ):
1526
+ def test_watch_unassigned_watcher_id (self ):
1526
1527
d = {}
1527
1528
with self .assertRaisesRegex (ValueError , r"No dict watcher set for ID 1" ):
1528
1529
self .watch (1 , d )
1529
1530
1531
+ def test_unwatch_non_dict (self ):
1532
+ with self .watcher () as wid :
1533
+ with self .assertRaisesRegex (ValueError , r"Cannot watch non-dictionary" ):
1534
+ self .unwatch (wid , 1 )
1535
+
1536
+ def test_unwatch_out_of_range_watcher_id (self ):
1537
+ d = {}
1538
+ with self .assertRaisesRegex (ValueError , r"Invalid dict watcher ID -1" ):
1539
+ self .unwatch (- 1 , d )
1540
+ with self .assertRaisesRegex (ValueError , r"Invalid dict watcher ID 8" ):
1541
+ self .unwatch (8 , d ) # DICT_MAX_WATCHERS = 8
1542
+
1543
+ def test_unwatch_unassigned_watcher_id (self ):
1544
+ d = {}
1545
+ with self .assertRaisesRegex (ValueError , r"No dict watcher set for ID 1" ):
1546
+ self .unwatch (1 , d )
1547
+
1548
+ def test_clear_out_of_range_watcher_id (self ):
1549
+ with self .assertRaisesRegex (ValueError , r"Invalid dict watcher ID -1" ):
1550
+ self .clear_watcher (- 1 )
1551
+ with self .assertRaisesRegex (ValueError , r"Invalid dict watcher ID 8" ):
1552
+ self .clear_watcher (8 ) # DICT_MAX_WATCHERS = 8
1553
+
1554
+ def test_clear_unassigned_watcher_id (self ):
1555
+ with self .assertRaisesRegex (ValueError , r"No dict watcher set for ID 1" ):
1556
+ self .clear_watcher (1 )
1557
+
1530
1558
1531
1559
if __name__ == "__main__" :
1532
1560
unittest .main ()
0 commit comments