Skip to content

Commit 61195c4

Browse files
committed
bpo-35983: further minor details
1 parent 5c86e23 commit 61195c4

File tree

4 files changed

+21
-7
lines changed

4 files changed

+21
-7
lines changed

Include/object.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -666,7 +666,7 @@ mytype_dealloc(mytype *p)
666666
Py_TRASHCAN_BEGIN(p, mytype_dealloc)
667667
... The body of the deallocator goes here, including all calls ...
668668
... to Py_DECREF on contained objects. ...
669-
Py_TRASHCAN_END
669+
Py_TRASHCAN_END // there should be no code after this
670670
}
671671
672672
CAUTION: Never return from the middle of the body! If the body needs to

Lib/test/test_capi.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -341,10 +341,18 @@ def test_trashcan_subclass(self):
341341
for i in range(1000):
342342
L = MyList((L,))
343343

344-
def test_trashcan_python_class(self):
344+
def test_trashcan_python_class1(self):
345+
self.do_test_trashcan_python_class(list)
346+
347+
def test_trashcan_python_class2(self):
348+
from _testcapi import MyList
349+
self.do_test_trashcan_python_class(MyList)
350+
351+
def do_test_trashcan_python_class(self, base):
345352
# Check that the trashcan mechanism works properly for a Python
346-
# subclass of a class using the trashcan (list in this test)
347-
class PyList(list):
353+
# subclass of a class using the trashcan (this specific test assumes
354+
# that the base class "base" behaves like list)
355+
class PyList(base):
348356
# Count the number of PyList instances to verify that there is
349357
# no memory leak
350358
num = 0
@@ -356,6 +364,8 @@ def __del__(self):
356364

357365
for parity in (0, 1):
358366
L = None
367+
# We need in the order of 2**20 iterations here such that a
368+
# typical 8MB stack would overflow without the trashcan.
359369
for i in range(2**20):
360370
L = PyList((L,))
361371
L.attr = i

Lib/test/test_ordered_dict.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,9 @@ def update(self, *args, **kwds):
459459
self.assertEqual(list(MyOD(items).items()), items)
460460

461461
def test_highly_nested(self):
462-
# Issue 25395: crashes during garbage collection
462+
# Issues 25395 and 35983: test that the trashcan mechanism works
463+
# correctly for OrderedDict: deleting a highly nested OrderDict
464+
# should not crash Python.
463465
OrderedDict = self.OrderedDict
464466
obj = None
465467
for _ in range(1000):
@@ -468,7 +470,9 @@ def test_highly_nested(self):
468470
support.gc_collect()
469471

470472
def test_highly_nested_subclass(self):
471-
# Issue 25395: crashes during garbage collection
473+
# Issues 25395 and 35983: test that the trashcan mechanism works
474+
# correctly for OrderedDict: deleting a highly nested OrderDict
475+
# should not crash Python.
472476
OrderedDict = self.OrderedDict
473477
deleted = []
474478
class MyOD(OrderedDict):

Modules/_testcapimodule.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5352,7 +5352,7 @@ MyList_dealloc(MyListObject* op)
53525352
if (op->deallocated) {
53535353
/* We cannot raise exceptions here but we still want the testsuite
53545354
* to fail when we hit this */
5355-
abort();
5355+
Py_FatalError("MyList instance deallocated twice");
53565356
}
53575357
op->deallocated = 1;
53585358
PyList_Type.tp_dealloc((PyObject *)op);

0 commit comments

Comments
 (0)