https://github.com/python/cpython/commit/4ff5d88fb1416d347bfd8bb53b0945adadc924ef commit: 4ff5d88fb1416d347bfd8bb53b0945adadc924ef branch: 3.13 author: Tomas R. <tomas.ro...@gmail.com> committer: serhiy-storchaka <storch...@gmail.com> date: 2025-04-13T08:42:04Z summary:
[3.13] gh-131927: Prevent emitting compiler warnings twice (GH-131993) (GH-132463) (cherry picked from commit 3d08c8ad20dfabd4864be139cd9c2eb5602ccdfe) files: M Include/cpython/warnings.h M Lib/test/test_compile.py M Python/_warnings.c M Python/compile.c diff --git a/Include/cpython/warnings.h b/Include/cpython/warnings.h index 4e3eb88e8ff447..8731fd2e96b716 100644 --- a/Include/cpython/warnings.h +++ b/Include/cpython/warnings.h @@ -18,3 +18,9 @@ PyAPI_FUNC(int) PyErr_WarnExplicitFormat( // DEPRECATED: Use PyErr_WarnEx() instead. #define PyErr_Warn(category, msg) PyErr_WarnEx((category), (msg), 1) + +int _PyErr_WarnExplicitObjectWithContext( + PyObject *category, + PyObject *message, + PyObject *filename, + int lineno); diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index ed4e6265eac438..b57adfadb5af5f 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -1512,6 +1512,24 @@ async def name_4(): pass [[]] + def test_compile_warnings(self): + # See gh-131927 + # Compile warnings originating from the same file and + # line are now only emitted once. + with warnings.catch_warnings(record=True) as caught: + warnings.simplefilter("default") + compile('1 is 1', '<stdin>', 'eval') + compile('1 is 1', '<stdin>', 'eval') + + self.assertEqual(len(caught), 1) + + with warnings.catch_warnings(record=True) as caught: + warnings.simplefilter("always") + compile('1 is 1', '<stdin>', 'eval') + compile('1 is 1', '<stdin>', 'eval') + + self.assertEqual(len(caught), 2) + @requires_debug_ranges() class TestSourcePositions(unittest.TestCase): # Ensure that compiled code snippets have correct line and column numbers diff --git a/Python/_warnings.c b/Python/_warnings.c index 4bb83b214ae6cc..5bbd4a9c19f6c9 100644 --- a/Python/_warnings.c +++ b/Python/_warnings.c @@ -1317,6 +1317,28 @@ PyErr_WarnExplicitObject(PyObject *category, PyObject *message, return 0; } +/* Like PyErr_WarnExplicitObject, but automatically sets up context */ +int +_PyErr_WarnExplicitObjectWithContext(PyObject *category, PyObject *message, + PyObject *filename, int lineno) +{ + PyObject *unused_filename, *module, *registry; + int unused_lineno; + int stack_level = 1; + + if (!setup_context(stack_level, NULL, &unused_filename, &unused_lineno, + &module, ®istry)) { + return -1; + } + + int rc = PyErr_WarnExplicitObject(category, message, filename, lineno, + module, registry); + Py_DECREF(unused_filename); + Py_DECREF(registry); + Py_DECREF(module); + return rc; +} + int PyErr_WarnExplicit(PyObject *category, const char *text, const char *filename_str, int lineno, diff --git a/Python/compile.c b/Python/compile.c index ba780927eff9d6..bb2c2293a38c9a 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -6616,8 +6616,8 @@ compiler_warn(struct compiler *c, location loc, if (msg == NULL) { return ERROR; } - if (PyErr_WarnExplicitObject(PyExc_SyntaxWarning, msg, c->c_filename, - loc.lineno, NULL, NULL) < 0) + if (_PyErr_WarnExplicitObjectWithContext(PyExc_SyntaxWarning, msg, + c->c_filename, loc.lineno) < 0) { if (PyErr_ExceptionMatches(PyExc_SyntaxWarning)) { /* Replace the SyntaxWarning exception with a SyntaxError _______________________________________________ Python-checkins mailing list -- python-checkins@python.org To unsubscribe send an email to python-checkins-le...@python.org https://mail.python.org/mailman3/lists/python-checkins.python.org/ Member address: arch...@mail-archive.com