Skip to content

Commit c6d77e8

Browse files
serhiy-storchakaclaude
authored andcommitted
gh-155146: Do not depend on the exact number of allocations in test_class (GH-155150)
Try to fail every one of the first allocations and accept the first one which fails in the code detaching the instance dictionary from the object, instead of assuming that this is the first allocation after set_nomemory(). Run the test with the test.support.isolation.runInSubprocess() decorator instead of executing it as a source string in a subprocess. (cherry picked from commit 416c346) Co-authored-by: Serhiy Storchaka <storchaka@gmail.com> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent 44b655c commit c6d77e8

1 file changed

Lines changed: 34 additions & 23 deletions

File tree

Lib/test/test_class.py

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import unittest
44
from test import support
5-
from test.support import cpython_only, import_helper, script_helper
5+
from test.support import cpython_only, import_helper, isolation
66

77
testmeths = [
88

@@ -996,32 +996,43 @@ class C:
996996
C.a = X()
997997

998998
@support.nomemtest
999+
@isolation.runInSubprocess()
9991000
def test_detach_materialized_dict_no_memory(self):
1000-
code = """if 1:
1001-
import test.support
1002-
import _testcapi
1003-
1004-
class A:
1005-
def __init__(self):
1006-
self.a = 1
1007-
self.b = 2
1001+
import _testcapi
1002+
1003+
class A:
1004+
def __init__(self):
1005+
self.a = 1
1006+
self.b = 2
1007+
1008+
# The failing allocation should be the one which detaches the
1009+
# dictionary from the object, but other allocations can happen
1010+
# first, so try to fail every one of the first allocations.
1011+
raised = False
1012+
for n in range(20):
10081013
a = A()
10091014
d = a.__dict__
1010-
with test.support.catch_unraisable_exception() as ex:
1011-
_testcapi.set_nomemory(0, 1)
1012-
del a
1013-
assert ex.unraisable.exc_type is MemoryError
10141015
try:
1015-
d["a"]
1016-
except KeyError:
1017-
pass
1018-
else:
1019-
assert False, "KeyError not raised"
1020-
"""
1021-
rc, out, err = script_helper.assert_python_ok("-c", code)
1022-
self.assertEqual(rc, 0)
1023-
self.assertFalse(out, msg=out.decode('utf-8'))
1024-
self.assertFalse(err, msg=err.decode('utf-8'))
1016+
with support.catch_unraisable_exception() as ex:
1017+
_testcapi.set_nomemory(n, n + 1)
1018+
try:
1019+
del a
1020+
finally:
1021+
_testcapi.remove_mem_hooks()
1022+
exc_type = ex.unraisable and ex.unraisable.exc_type
1023+
except MemoryError:
1024+
# The failing allocation was not in the deallocation code.
1025+
continue
1026+
if exc_type is not MemoryError:
1027+
continue
1028+
raised = True
1029+
if "a" not in d:
1030+
# The dictionary was cleared, as expected.
1031+
break
1032+
else:
1033+
if not raised:
1034+
self.fail("MemoryError was not raised during deallocation")
1035+
self.fail("the dictionary was not cleared")
10251036

10261037
if __name__ == '__main__':
10271038
unittest.main()

0 commit comments

Comments
 (0)