https://github.com/python/cpython/commit/4ff5d88fb1416d347bfd8bb53b0945adadc924ef
commit: 4ff5d88fb1416d347bfd8bb53b0945adadc924ef
branch: 3.13
author: Tomas R. <[email protected]>
committer: serhiy-storchaka <[email protected]>
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 -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]