Skip to content

Commit ea5336e

Browse files
authored
Merge branch 'main' into gh-ndim-validation-hardening
2 parents 1d41002 + c8ee196 commit ea5336e

File tree

10 files changed

+75
-14
lines changed

10 files changed

+75
-14
lines changed

Lib/test/test_exceptions.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2561,6 +2561,30 @@ def test_incorrect_constructor(self):
25612561
args = ("bad.py", 1, 2, "abcdefg", 1)
25622562
self.assertRaises(TypeError, SyntaxError, "bad bad", args)
25632563

2564+
def test_syntax_error_memory_leak(self):
2565+
# gh-146250: memory leak with re-initialization of SyntaxError
2566+
e = SyntaxError("msg", ("file.py", 1, 2, "txt", 2, 3))
2567+
e.__init__("new_msg", ("new_file.py", 2, 3, "new_txt", 3, 4))
2568+
self.assertEqual(e.msg, "new_msg")
2569+
self.assertEqual(e.args, ("new_msg", ("new_file.py", 2, 3, "new_txt", 3, 4)))
2570+
self.assertEqual(e.filename, "new_file.py")
2571+
self.assertEqual(e.lineno, 2)
2572+
self.assertEqual(e.offset, 3)
2573+
self.assertEqual(e.text, "new_txt")
2574+
self.assertEqual(e.end_lineno, 3)
2575+
self.assertEqual(e.end_offset, 4)
2576+
2577+
e = SyntaxError("msg", ("file.py", 1, 2, "txt", 2, 3))
2578+
e.__init__("new_msg", ("new_file.py", 2, 3, "new_txt"))
2579+
self.assertEqual(e.msg, "new_msg")
2580+
self.assertEqual(e.args, ("new_msg", ("new_file.py", 2, 3, "new_txt")))
2581+
self.assertEqual(e.filename, "new_file.py")
2582+
self.assertEqual(e.lineno, 2)
2583+
self.assertEqual(e.offset, 3)
2584+
self.assertEqual(e.text, "new_txt")
2585+
self.assertIsNone(e.end_lineno)
2586+
self.assertIsNone(e.end_offset)
2587+
25642588

25652589
class TestInvalidExceptionMatcher(unittest.TestCase):
25662590
def test_except_star_invalid_exception_type(self):

Lib/test/test_free_threading/test_itertools.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import unittest
2-
from itertools import accumulate, batched, chain, combinations_with_replacement, cycle, permutations
2+
from itertools import accumulate, batched, chain, combinations_with_replacement, cycle, permutations, zip_longest
33
from test.support import threading_helper
44

55

@@ -62,6 +62,13 @@ def test_permutations(self):
6262
it = permutations(tuple(range(4)), 2)
6363
threading_helper.run_concurrently(work_iterator, nthreads=6, args=[it])
6464

65+
@threading_helper.reap_threads
66+
def test_zip_longest(self):
67+
number_of_iterations = 10
68+
for _ in range(number_of_iterations):
69+
it = zip_longest(list(range(4)), list(range(8)), fillvalue=0)
70+
threading_helper.run_concurrently(work_iterator, nthreads=10, args=[it])
71+
6572

6673
if __name__ == "__main__":
6774
unittest.main()
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fixed a memory leak in :exc:`SyntaxError` when re-initializing it.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Adds a null check to handle when the JIT optimizer runs out of space when dealing with contradictions in ``make_bottom``.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Make concurrent iteration over :class:`itertools.zip_longest` safe under free-threading.

Modules/itertoolsmodule.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3876,7 +3876,7 @@ zip_longest_traverse(PyObject *op, visitproc visit, void *arg)
38763876
}
38773877

38783878
static PyObject *
3879-
zip_longest_next(PyObject *op)
3879+
zip_longest_next_lock_held(PyObject *op)
38803880
{
38813881
ziplongestobject *lz = ziplongestobject_CAST(op);
38823882
Py_ssize_t i;
@@ -3947,6 +3947,16 @@ zip_longest_next(PyObject *op)
39473947
return result;
39483948
}
39493949

3950+
static PyObject *
3951+
zip_longest_next(PyObject *op)
3952+
{
3953+
PyObject *result;
3954+
Py_BEGIN_CRITICAL_SECTION(op);
3955+
result = zip_longest_next_lock_held(op);
3956+
Py_END_CRITICAL_SECTION()
3957+
return result;
3958+
}
3959+
39503960
PyDoc_STRVAR(zip_longest_doc,
39513961
"zip_longest(*iterables, fillvalue=None)\n\
39523962
--\n\

Objects/exceptions.c

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2802,23 +2802,25 @@ SyntaxError_init(PyObject *op, PyObject *args, PyObject *kwds)
28022802
return -1;
28032803
}
28042804

2805-
self->end_lineno = NULL;
2806-
self->end_offset = NULL;
2805+
PyObject *filename, *lineno, *offset, *text;
2806+
PyObject *end_lineno = NULL;
2807+
PyObject *end_offset = NULL;
2808+
PyObject *metadata = NULL;
28072809
if (!PyArg_ParseTuple(info, "OOOO|OOO",
2808-
&self->filename, &self->lineno,
2809-
&self->offset, &self->text,
2810-
&self->end_lineno, &self->end_offset, &self->metadata)) {
2810+
&filename, &lineno,
2811+
&offset, &text,
2812+
&end_lineno, &end_offset, &metadata)) {
28112813
Py_DECREF(info);
28122814
return -1;
28132815
}
28142816

2815-
Py_INCREF(self->filename);
2816-
Py_INCREF(self->lineno);
2817-
Py_INCREF(self->offset);
2818-
Py_INCREF(self->text);
2819-
Py_XINCREF(self->end_lineno);
2820-
Py_XINCREF(self->end_offset);
2821-
Py_XINCREF(self->metadata);
2817+
Py_XSETREF(self->filename, Py_NewRef(filename));
2818+
Py_XSETREF(self->lineno, Py_NewRef(lineno));
2819+
Py_XSETREF(self->offset, Py_NewRef(offset));
2820+
Py_XSETREF(self->text, Py_NewRef(text));
2821+
Py_XSETREF(self->end_lineno, Py_XNewRef(end_lineno));
2822+
Py_XSETREF(self->end_offset, Py_XNewRef(end_offset));
2823+
Py_XSETREF(self->metadata, Py_XNewRef(metadata));
28222824
Py_DECREF(info);
28232825

28242826
if (self->end_lineno != NULL && self->end_offset == NULL) {

Python/optimizer_symbols.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1684,6 +1684,9 @@ static JitOptSymbol *
16841684
make_bottom(JitOptContext *ctx)
16851685
{
16861686
JitOptSymbol *sym = sym_new(ctx);
1687+
if (sym == NULL) {
1688+
return out_of_space(ctx);
1689+
}
16871690
sym->tag = JIT_SYM_BOTTOM_TAG;
16881691
return sym;
16891692
}

configure

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

configure.ac

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,9 @@ then
342342
*-*-darwin*)
343343
ac_sys_system=Darwin
344344
;;
345+
*-gnu)
346+
ac_sys_system=GNU
347+
;;
345348
*-*-vxworks*)
346349
ac_sys_system=VxWorks
347350
;;
@@ -780,6 +783,9 @@ if test "$cross_compiling" = yes; then
780783
_host_ident=$host_cpu
781784
esac
782785
;;
786+
*-gnu)
787+
_host_ident=$host_cpu
788+
;;
783789
*-*-cygwin*)
784790
_host_ident=
785791
;;

0 commit comments

Comments
 (0)