From f0d89175ad7ef7afde35ce7838ff71298d04b8a5 Mon Sep 17 00:00:00 2001 From: "Tomas R." Date: Sat, 12 Apr 2025 12:34:36 +0200 Subject: [PATCH 1/2] [3.13] gh-131927: Prevent emitting optimizer warnings twice in the REPL (GH-131993) (cherry picked from commit 3d08c8ad20dfabd4864be139cd9c2eb5602ccdfe) Co-authored-by: Tomas R. --- Include/cpython/warnings.h | 6 ++++++ Lib/test/test_compile.py | 18 ++++++++++++++++++ Lib/test/test_pyrepl/test_interact.py | 1 + Python/_warnings.c | 22 ++++++++++++++++++++++ Python/compile.c | 4 ++-- 5 files changed, 49 insertions(+), 2 deletions(-) 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', '', 'eval') + compile('1 is 1', '', 'eval') + + self.assertEqual(len(caught), 1) + + with warnings.catch_warnings(record=True) as caught: + warnings.simplefilter("always") + compile('1 is 1', '', 'eval') + compile('1 is 1', '', '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/Lib/test/test_pyrepl/test_interact.py b/Lib/test/test_pyrepl/test_interact.py index 2041a35c8a472b..dce79256d7045d 100644 --- a/Lib/test/test_pyrepl/test_interact.py +++ b/Lib/test/test_pyrepl/test_interact.py @@ -1,6 +1,7 @@ import contextlib import io import unittest +import warnings from unittest.mock import patch from textwrap import dedent 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 From 99d3b5be93da85d449a4745b7489a39bc856660c Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sun, 13 Apr 2025 11:18:26 +0300 Subject: [PATCH 2/2] Update test_interact.py --- Lib/test/test_pyrepl/test_interact.py | 1 - 1 file changed, 1 deletion(-) diff --git a/Lib/test/test_pyrepl/test_interact.py b/Lib/test/test_pyrepl/test_interact.py index dce79256d7045d..2041a35c8a472b 100644 --- a/Lib/test/test_pyrepl/test_interact.py +++ b/Lib/test/test_pyrepl/test_interact.py @@ -1,7 +1,6 @@ import contextlib import io import unittest -import warnings from unittest.mock import patch from textwrap import dedent pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy