summaryrefslogtreecommitdiffstats
path: root/Lib/test/test_capi
diff options
context:
space:
mode:
authorMark Shannon <mark@hotpy.org>2024-12-11 14:02:59 (GMT)
committerGitHub <noreply@github.com>2024-12-11 14:02:59 (GMT)
commit5a23994a3dbee43a0b08f5920032f60f38b63071 (patch)
treee2fad9c3a8a3204f2e155d3fff61d733231c4003 /Lib/test/test_capi
parent359389ed51aecc107681e600b71852c0a97304e1 (diff)
downloadcpython-5a23994a3dbee43a0b08f5920032f60f38b63071.zip
cpython-5a23994a3dbee43a0b08f5920032f60f38b63071.tar.gz
cpython-5a23994a3dbee43a0b08f5920032f60f38b63071.tar.bz2
GH-127058: Make `PySequence_Tuple` safer and probably faster. (#127758)
* Use a small buffer, then list when constructing a tuple from an arbitrary sequence.
Diffstat (limited to 'Lib/test/test_capi')
-rw-r--r--Lib/test/test_capi/test_tuple.py25
1 files changed, 25 insertions, 0 deletions
diff --git a/Lib/test/test_capi/test_tuple.py b/Lib/test/test_capi/test_tuple.py
index e6b49ca..6349467 100644
--- a/Lib/test/test_capi/test_tuple.py
+++ b/Lib/test/test_capi/test_tuple.py
@@ -1,5 +1,6 @@
import unittest
import sys
+import gc
from collections import namedtuple
from test.support import import_helper
@@ -257,5 +258,29 @@ class CAPITest(unittest.TestCase):
self.assertRaises(SystemError, resize, [1, 2, 3], 0, False)
self.assertRaises(SystemError, resize, NULL, 0, False)
+ def test_bug_59313(self):
+ # Before 3.14, the C-API function PySequence_Tuple
+ # would create incomplete tuples which were visible to
+ # the cycle GC, and this test would crash the interpeter.
+ TAG = object()
+ tuples = []
+
+ def referrer_tuples():
+ return [x for x in gc.get_referrers(TAG)
+ if isinstance(x, tuple)]
+
+ def my_iter():
+ nonlocal tuples
+ yield TAG # 'tag' gets stored in the result tuple
+ tuples += referrer_tuples()
+ for x in range(10):
+ tuples += referrer_tuples()
+ # Prior to 3.13 would raise a SystemError when the tuple needs to be resized
+ yield x
+
+ self.assertEqual(tuple(my_iter()), (TAG, *range(10)))
+ self.assertEqual(tuples, [])
+
+
if __name__ == "__main__":
unittest.main()