@@ -18,6 +18,8 @@ def verify_instance_interface(self, ins):
1818 "%s missing %s attribute" %
1919 (ins .__class__ .__name__ , attr ))
2020
21+ # TODO: RUSTPYTHON
22+ @unittest .expectedFailure
2123 def test_inheritance (self ):
2224 # Make sure the inheritance hierarchy matches the documentation
2325 exc_set = set ()
@@ -28,8 +30,9 @@ def test_inheritance(self):
2830 except TypeError :
2931 pass
3032
31- inheritance_tree = open (os .path .join (os .path .split (__file__ )[0 ],
32- 'exception_hierarchy.txt' ))
33+ inheritance_tree = open (
34+ os .path .join (os .path .split (__file__ )[0 ], 'exception_hierarchy.txt' ),
35+ encoding = "utf-8" )
3336 try :
3437 superclass_name = inheritance_tree .readline ().rstrip ()
3538 try :
@@ -43,7 +46,7 @@ def test_inheritance(self):
4346 last_depth = 0
4447 for exc_line in inheritance_tree :
4548 exc_line = exc_line .rstrip ()
46- depth = exc_line .rindex ('- ' )
49+ depth = exc_line .rindex ('─ ' )
4750 exc_name = exc_line [depth + 2 :] # Slice past space
4851 if '(' in exc_name :
4952 paren_index = exc_name .index ('(' )
@@ -117,6 +120,33 @@ def test_interface_no_arg(self):
117120 [repr (exc ), exc .__class__ .__name__ + '()' ])
118121 self .interface_test_driver (results )
119122
123+ # TODO: RUSTPYTHON
124+ @unittest .expectedFailure
125+ def test_setstate_refcount_no_crash (self ):
126+ # gh-97591: Acquire strong reference before calling tp_hash slot
127+ # in PyObject_SetAttr.
128+ import gc
129+ d = {}
130+ class HashThisKeyWillClearTheDict (str ):
131+ def __hash__ (self ) -> int :
132+ d .clear ()
133+ return super ().__hash__ ()
134+ class Value (str ):
135+ pass
136+ exc = Exception ()
137+
138+ d [HashThisKeyWillClearTheDict ()] = Value () # refcount of Value() is 1 now
139+
140+ # Exception.__setstate__ should aquire a strong reference of key and
141+ # value in the dict. Otherwise, Value()'s refcount would go below
142+ # zero in the tp_hash call in PyObject_SetAttr(), and it would cause
143+ # crash in GC.
144+ exc .__setstate__ (d ) # __hash__() is called again here, clearing the dict.
145+
146+ # This GC would crash if the refcount of Value() goes below zero.
147+ gc .collect ()
148+
149+
120150class UsageTests (unittest .TestCase ):
121151
122152 """Test usage of exceptions"""
0 commit comments