diff options
author | Mark Shannon <mark@hotpy.org> | 2024-12-11 14:02:59 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-12-11 14:02:59 (GMT) |
commit | 5a23994a3dbee43a0b08f5920032f60f38b63071 (patch) | |
tree | e2fad9c3a8a3204f2e155d3fff61d733231c4003 /Lib/test/test_capi | |
parent | 359389ed51aecc107681e600b71852c0a97304e1 (diff) | |
download | cpython-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.py | 25 |
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() |