Skip to content

Commit a7b8768

Browse files
CPython Developersdalinaum
authored andcommitted
Update test_baseexception.py from cpython 3.11.2
1 parent 4e19be7 commit a7b8768

File tree

1 file changed

+29
-3
lines changed

1 file changed

+29
-3
lines changed

Lib/test/test_baseexception.py

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,9 @@ def test_inheritance(self):
2828
except TypeError:
2929
pass
3030

31-
inheritance_tree = open(os.path.join(os.path.split(__file__)[0],
32-
'exception_hierarchy.txt'))
31+
inheritance_tree = open(
32+
os.path.join(os.path.split(__file__)[0], 'exception_hierarchy.txt'),
33+
encoding="utf-8")
3334
try:
3435
superclass_name = inheritance_tree.readline().rstrip()
3536
try:
@@ -43,7 +44,7 @@ def test_inheritance(self):
4344
last_depth = 0
4445
for exc_line in inheritance_tree:
4546
exc_line = exc_line.rstrip()
46-
depth = exc_line.rindex('-')
47+
depth = exc_line.rindex('')
4748
exc_name = exc_line[depth+2:] # Slice past space
4849
if '(' in exc_name:
4950
paren_index = exc_name.index('(')
@@ -117,6 +118,31 @@ def test_interface_no_arg(self):
117118
[repr(exc), exc.__class__.__name__ + '()'])
118119
self.interface_test_driver(results)
119120

121+
def test_setstate_refcount_no_crash(self):
122+
# gh-97591: Acquire strong reference before calling tp_hash slot
123+
# in PyObject_SetAttr.
124+
import gc
125+
d = {}
126+
class HashThisKeyWillClearTheDict(str):
127+
def __hash__(self) -> int:
128+
d.clear()
129+
return super().__hash__()
130+
class Value(str):
131+
pass
132+
exc = Exception()
133+
134+
d[HashThisKeyWillClearTheDict()] = Value() # refcount of Value() is 1 now
135+
136+
# Exception.__setstate__ should aquire a strong reference of key and
137+
# value in the dict. Otherwise, Value()'s refcount would go below
138+
# zero in the tp_hash call in PyObject_SetAttr(), and it would cause
139+
# crash in GC.
140+
exc.__setstate__(d) # __hash__() is called again here, clearing the dict.
141+
142+
# This GC would crash if the refcount of Value() goes below zero.
143+
gc.collect()
144+
145+
120146
class UsageTests(unittest.TestCase):
121147

122148
"""Test usage of exceptions"""

0 commit comments

Comments
 (0)