Bug report
test_class.TestInlineValues.test_detach_materialized_dict_no_memory (added in gh-124547) uses _testcapi.set_nomemory(0, 1) to fail the first allocation after that call, and assumes that this is the allocation which detaches the instance dictionary from the object. But set_nomemory() hooks all three allocator domains, so any other allocation which happens first consumes the single failure.
The target is one allocation wide. Failing the n-th allocation instead on Linux: n=0 works as intended, n=1..4 kill the process with MemoryError, and for n>=5 no MemoryError occurs during deallocation at all.
The test subprocess imports only test.support and _testcapi, so any change of what test.support allocates at import time can shift the sequence.
#155120 is such a change: it adds three functions and a constant to Lib/test/support/__init__.py, none of which is used by this test. With it the test fails on the Windows / Build and test (x64, tail-call) job:
assert False, "KeyError not raised"
AssertionError: KeyError not raised
MemoryError was reported as unraisable during deallocation, but the dictionary was not cleared, because the failing allocation was not the one in the detach code. This is deterministic — 3 failures out of 3, including a re-run of the same commit — while the same job passes on the last 6 commits on main and on the other recent pull requests I checked. It does not reproduce on Linux, nor on the other Windows configurations.
The tested invariant is correct, only the way it is tested is fragile. I propose to try to fail each of the first allocations and to accept the first one which fails in the detach code.
Linked PRs
Bug report
test_class.TestInlineValues.test_detach_materialized_dict_no_memory(added in gh-124547) uses_testcapi.set_nomemory(0, 1)to fail the first allocation after that call, and assumes that this is the allocation which detaches the instance dictionary from the object. Butset_nomemory()hooks all three allocator domains, so any other allocation which happens first consumes the single failure.The target is one allocation wide. Failing the n-th allocation instead on Linux: n=0 works as intended, n=1..4 kill the process with
MemoryError, and for n>=5 noMemoryErroroccurs during deallocation at all.The test subprocess imports only
test.supportand_testcapi, so any change of whattest.supportallocates at import time can shift the sequence.#155120 is such a change: it adds three functions and a constant to
Lib/test/support/__init__.py, none of which is used by this test. With it the test fails on theWindows / Build and test (x64, tail-call)job:MemoryErrorwas reported as unraisable during deallocation, but the dictionary was not cleared, because the failing allocation was not the one in the detach code. This is deterministic — 3 failures out of 3, including a re-run of the same commit — while the same job passes on the last 6 commits on main and on the other recent pull requests I checked. It does not reproduce on Linux, nor on the other Windows configurations.The tested invariant is correct, only the way it is tested is fragile. I propose to try to fail each of the first allocations and to accept the first one which fails in the detach code.
Linked PRs