Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions Include/cpython/warnings.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
18 changes: 18 additions & 0 deletions Lib/test/test_compile.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions Lib/test/test_pyrepl/test_interact.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import contextlib
import io
import unittest
import warnings
from unittest.mock import patch
from textwrap import dedent

Expand Down
22 changes: 22 additions & 0 deletions Python/_warnings.c
Original file line number Diff line number Diff line change
Expand Up @@ -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, &registry)) {
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,
Expand Down
4 changes: 2 additions & 2 deletions Python/compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a note, 3.13 uses compiler_warn instead of _PyErr_EmitSyntaxWarning to emit warnings.

c->c_filename, loc.lineno) < 0)
{
if (PyErr_ExceptionMatches(PyExc_SyntaxWarning)) {
/* Replace the SyntaxWarning exception with a SyntaxError
Expand Down
Loading