@@ -18,6 +18,8 @@ def verify_instance_interface(self, ins):
18
18
"%s missing %s attribute" %
19
19
(ins .__class__ .__name__ , attr ))
20
20
21
+ # TODO: RUSTPYTHON
22
+ @unittest .expectedFailure
21
23
def test_inheritance (self ):
22
24
# Make sure the inheritance hierarchy matches the documentation
23
25
exc_set = set ()
@@ -28,8 +30,9 @@ def test_inheritance(self):
28
30
except TypeError :
29
31
pass
30
32
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" )
33
36
try :
34
37
superclass_name = inheritance_tree .readline ().rstrip ()
35
38
try :
@@ -43,7 +46,7 @@ def test_inheritance(self):
43
46
last_depth = 0
44
47
for exc_line in inheritance_tree :
45
48
exc_line = exc_line .rstrip ()
46
- depth = exc_line .rindex ('- ' )
49
+ depth = exc_line .rindex ('─ ' )
47
50
exc_name = exc_line [depth + 2 :] # Slice past space
48
51
if '(' in exc_name :
49
52
paren_index = exc_name .index ('(' )
@@ -117,6 +120,33 @@ def test_interface_no_arg(self):
117
120
[repr (exc ), exc .__class__ .__name__ + '()' ])
118
121
self .interface_test_driver (results )
119
122
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
+
120
150
class UsageTests (unittest .TestCase ):
121
151
122
152
"""Test usage of exceptions"""
0 commit comments