Skip to content

Commit 77a0373

Browse files
Review addressed
1 parent 9ce41be commit 77a0373

File tree

3 files changed

+50
-3
lines changed

3 files changed

+50
-3
lines changed

Lib/test/test_capi/test_tuple.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,17 @@ class TupleSubclass(tuple):
1414

1515

1616
class CAPITest(unittest.TestCase):
17+
def _not_tracked(self, t):
18+
# There is no need for gc.collect()
19+
# since we don't track these tuples at all.
20+
self.assertFalse(gc.is_tracked(t), t)
21+
22+
def _tracked(self, t):
23+
self.assertTrue(gc.is_tracked(t), t)
24+
gc.collect()
25+
gc.collect()
26+
self.assertTrue(gc.is_tracked(t), t)
27+
1728
def test_check(self):
1829
# Test PyTuple_Check()
1930
check = _testlimitedcapi.tuple_check
@@ -52,11 +63,14 @@ def test_tuple_new(self):
5263
self.assertEqual(tup1, ())
5364
self.assertEqual(size(tup1), 0)
5465
self.assertIs(type(tup1), tuple)
66+
self._not_tracked(tup1)
67+
5568
tup2 = tuple_new(1)
5669
self.assertIs(type(tup2), tuple)
5770
self.assertEqual(size(tup2), 1)
5871
self.assertIsNot(tup2, tup1)
5972
self.assertTrue(checknull(tup2, 0))
73+
self._tracked(tup2)
6074

6175
self.assertRaises(SystemError, tuple_new, -1)
6276
self.assertRaises(SystemError, tuple_new, PY_SSIZE_T_MIN)
@@ -69,6 +83,12 @@ def test_tuple_fromarray(self):
6983
tup = tuple([i] for i in range(5))
7084
copy = tuple_fromarray(tup)
7185
self.assertEqual(copy, tup)
86+
self._tracked(copy)
87+
88+
tup = tuple((42**i, 0) for i in range(5))
89+
copy = tuple_fromarray(tup)
90+
self.assertEqual(copy, tup)
91+
self._not_tracked(copy)
7292

7393
tup = ()
7494
copy = tuple_fromarray(tup)
@@ -92,11 +112,16 @@ def test_tuple_pack(self):
92112
self.assertEqual(pack(1, [1]), ([1],))
93113
self.assertEqual(pack(2, [1], [2]), ([1], [2]))
94114

115+
self._tracked(pack(1, [1]))
116+
self._tracked(pack(2, [1], b'abc'))
117+
self._not_tracked(pack(2, 42, b'abc'))
118+
95119
self.assertRaises(SystemError, pack, PY_SSIZE_T_MIN)
96120
self.assertRaises(SystemError, pack, -1)
97121
self.assertRaises(MemoryError, pack, PY_SSIZE_T_MAX)
98122

99123
# CRASHES pack(1, NULL)
124+
# CRASHES pack(1, None)
100125
# CRASHES pack(2, [1])
101126

102127
def test_tuple_size(self):

Lib/test/test_tuple.py

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -291,9 +291,8 @@ def test_repr(self):
291291
self.assertEqual(repr(a2), "(0, 1, 2)")
292292

293293
def _not_tracked(self, t):
294-
# Nested tuples can take several collections to untrack
295-
gc.collect()
296-
gc.collect()
294+
# There is no need for gc.collect()
295+
# since we don't track these tuples at all.
297296
self.assertFalse(gc.is_tracked(t), t)
298297

299298
def _tracked(self, t):
@@ -323,6 +322,19 @@ def test_track_literals(self):
323322
self._tracked((set(),))
324323
self._tracked((x, y, z))
325324

325+
@support.cpython_only
326+
def test_track_after_operations(self):
327+
x, y, z = 1.5, "a", []
328+
329+
self._not_tracked((x, y) + (x, y))
330+
self._tracked((x, y) + (z,))
331+
332+
self._not_tracked((x, y) * 5)
333+
self._tracked((y, z) * 5)
334+
335+
self._not_tracked((x, y, z)[:2])
336+
self._tracked((x, y, z)[2:])
337+
326338
def check_track_dynamic(self, tp, always_track):
327339
x, y, z = 1.5, "a", []
328340

@@ -343,6 +355,14 @@ def check_track_dynamic(self, tp, always_track):
343355
self._tracked(tp(tuple([obj]) for obj in [x, y, z]))
344356
self._tracked(tuple(tp([obj]) for obj in [x, y, z]))
345357

358+
t = tp([1, x, y, z])
359+
self.assertEqual(type(t), tp)
360+
self._tracked(t)
361+
self.assertEqual(type(t[:]), tuple)
362+
self._tracked(t[:])
363+
self.assertEqual(type(t[:3]), tuple)
364+
self._not_tracked(t[:3])
365+
346366
@support.cpython_only
347367
def test_track_dynamic(self):
348368
# Test GC-optimization of dynamically constructed tuples.

Objects/tupleobject.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,8 @@ _PyTuple_MaybeUntrack(PyObject *op)
156156
_PyObject_GC_UNTRACK(op);
157157
}
158158

159+
/* This function helps to avoids performance issue in the GC,
160+
* we don't track immutable tuples. */
159161
static bool
160162
tuple_need_tracking(PyTupleObject *self)
161163
{

0 commit comments

Comments
 (0)