Skip to content

Commit b2b039c

Browse files
Address review
1 parent ff42c31 commit b2b039c

2 files changed

Lines changed: 32 additions & 5 deletions

File tree

‎Lib/test/test_tuple.py‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,9 @@ def test_repr(self):
294294
def _not_tracked_instantly(self, t):
295295
self.assertFalse(gc.is_tracked(t), t)
296296

297+
def _tracked_instantly(self, t):
298+
self.assertTrue(gc.is_tracked(t), t)
299+
297300
# Checks that t is not tracked after GC collection.
298301
def _not_tracked(self, t):
299302
# Nested tuples can take several collections to untrack
@@ -323,10 +326,14 @@ def test_track_literals(self):
323326
self._not_tracked_instantly((object(),))
324327

325328
# Test for _PyTuple_Concat
326-
self._not_tracked_instantly((1, 2) + (2, 3))
329+
self._not_tracked_instantly((1, 2) + (2, 3, 4))
330+
self._not_tracked_instantly((x, y,) + (2, 3))
331+
self._tracked_instantly((3, 4, 5, [],) + (2, 3))
327332

328333
# Test for _PyTuple_Repeat
329334
self._not_tracked_instantly((1, 2) * 5)
335+
self._not_tracked_instantly((1, x) * 5)
336+
self._tracked_instantly((1, []) * 5)
330337

331338
self._not_tracked(((1, x), y, (2, 3)))
332339
self._not_tracked((1, 2, (None, True, False, ()), int))

‎Python/flowgraph.c‎

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
#include "pycore_opcode_metadata.h" // OPCODE_HAS_ARG, etc
1313
#include "pycore_pystate.h" // _PyInterpreterState_GET()
1414
#include "pycore_stackref.h" // PyStackRef_AsPyObjectBorrow()
15-
#include "pycore_tuple.h" // _PyTuple_MaybeUntrack()
1615

1716
#include <stdbool.h>
1817

@@ -1553,6 +1552,8 @@ fold_tuple_of_constants(basicblock *bb, int i, PyObject *consts,
15531552
if (const_tuple == NULL) {
15541553
return ERROR;
15551554
}
1555+
PyObject_GC_UnTrack(const_tuple);
1556+
bool track_tuple = false;
15561557

15571558
for (int i = 0; i < seq_size; i++) {
15581559
cfg_instr *inst = const_instrs[i];
@@ -1563,8 +1564,13 @@ fold_tuple_of_constants(basicblock *bb, int i, PyObject *consts,
15631564
return ERROR;
15641565
}
15651566
PyTuple_SET_ITEM(const_tuple, i, element);
1567+
if (!track_tuple && PyObject_GC_IsTracked(element)) {
1568+
track_tuple = true;
1569+
}
1570+
}
1571+
if (track_tuple) {
1572+
_PyObject_GC_TRACK(const_tuple);
15661573
}
1567-
_PyTuple_MaybeUntrack(const_tuple);
15681574

15691575
nop_out(const_instrs, seq_size);
15701576
return instr_make_load_const(instr, const_tuple, consts, const_cache, consts_index);
@@ -1634,6 +1640,8 @@ fold_constant_seq_into_load_const(basicblock *bb, int i,
16341640
if (newconst == NULL) {
16351641
return ERROR;
16361642
}
1643+
PyObject_GC_UnTrack(newconst);
1644+
bool track_tuple = false;
16371645

16381646
int newpos_start = expected_append ? i - 1 : i;
16391647
for (int newpos = newpos_start; newpos >= pos; newpos--) {
@@ -1649,10 +1657,15 @@ fold_constant_seq_into_load_const(basicblock *bb, int i,
16491657
}
16501658
assert(consts_found > 0);
16511659
PyTuple_SET_ITEM(newconst, --consts_found, constant);
1660+
if (!track_tuple && PyObject_GC_IsTracked(constant)) {
1661+
track_tuple = true;
1662+
}
16521663
}
16531664
nop_out(&instr, 1);
16541665
}
1655-
_PyTuple_MaybeUntrack(newconst);
1666+
if (track_tuple) {
1667+
_PyObject_GC_TRACK(newconst);
1668+
}
16561669
assert(consts_found == 0);
16571670

16581671
if (build_op == BUILD_SET) {
@@ -1729,6 +1742,8 @@ optimize_lists_and_sets(basicblock *bb, int i, int nextop,
17291742
if (const_result == NULL) {
17301743
return ERROR;
17311744
}
1745+
PyObject_GC_UnTrack(const_result);
1746+
bool track_tuple = false;
17321747

17331748
for (int i = 0; i < seq_size; i++) {
17341749
cfg_instr *inst = const_instrs[i];
@@ -1739,8 +1754,13 @@ optimize_lists_and_sets(basicblock *bb, int i, int nextop,
17391754
return ERROR;
17401755
}
17411756
PyTuple_SET_ITEM(const_result, i, element);
1757+
if (!track_tuple && PyObject_GC_IsTracked(element)) {
1758+
track_tuple = true;
1759+
}
1760+
}
1761+
if (track_tuple) {
1762+
_PyObject_GC_TRACK(const_result);
17421763
}
1743-
_PyTuple_MaybeUntrack(const_result);
17441764

17451765
if (instr->i_opcode == BUILD_SET) {
17461766
PyObject *frozenset = PyFrozenSet_New(const_result);

0 commit comments

Comments
 (0)