Skip to content

Commit 18e832f

Browse files
committed
Revert "Always track frozenset in the GC"
This reverts commit 37ab323.
1 parent 7242fb4 commit 18e832f

2 files changed

Lines changed: 18 additions & 9 deletions

File tree

‎Lib/test/test_capi/test_set.py‎

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -392,10 +392,11 @@ def test_update_array_steal(self):
392392
self.check_update_method('update_array_steal')
393393

394394
def test_finish(self):
395-
# Test PyFrozenSetWriter_Finish(): track the frozenset in the GC
395+
# Test PyFrozenSetWriter_Finish(): track the frozenset in the GC if at
396+
# least one item is tracked by the GC
396397
writer = self.create_writer()
397398
writer.update([2, 5, 7])
398-
self.assertTrue(gc.is_tracked(writer.finish()))
399+
self.assertFalse(gc.is_tracked(writer.finish()))
399400

400401
class MyObject:
401402
pass
@@ -429,8 +430,8 @@ def test_discard(self):
429430

430431
@threading_helper.requires_working_threading()
431432
def test_thread(self):
432-
# PyFrozenSetWriter can be used by multiple threads: it's up to the
433-
# caller to implement a lock to prevent concurrent accesses.
433+
# PyFrozenSetWriter can be used by multiple threads: it's up to the caller
434+
# to implement a lock to prevent concurrent accesses.
434435
writer = self.create_writer()
435436

436437
def thread_func(writer):

‎Objects/setobject.c‎

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3287,13 +3287,21 @@ PyObject*
32873287
PyFrozenSetWriter_Finish(PyFrozenSetWriter *writer)
32883288
{
32893289
assert(frozensetwriter_check_consistency(writer));
3290-
PyObject *frozenset = _PyObject_CAST(writer);
3290+
PySetObject *frozenset = _PySet_CAST(writer);
32913291

3292-
// Now that the frozenset is fully initialized, it's safe to track it
3293-
// in the garbage collector.
3294-
_PyObject_GC_TRACK(frozenset);
3292+
// Now that the frozenset is fully initialized, it's safe to track it in
3293+
// the GC. Track the frozenset if at least one item is tracked by the GC.
3294+
Py_ssize_t pos = 0;
3295+
setentry *entry;
3296+
while (set_next(frozenset, &pos, &entry)) {
3297+
PyObject *item = entry->key;
3298+
if (_PyObject_IS_GC(item) && _PyObject_GC_IS_TRACKED(item)) {
3299+
_PyObject_GC_TRACK(frozenset);
3300+
break;
3301+
}
3302+
}
32953303

3296-
return frozenset;
3304+
return _PyObject_CAST(frozenset);
32973305
}
32983306

32993307

0 commit comments

Comments
 (0)