From c6d06026cb9a28054d72c803fd9db63ea8f09f03 Mon Sep 17 00:00:00 2001 From: AZero13 Date: Fri, 26 Dec 2025 17:19:18 -0500 Subject: [PATCH 1/3] gh-143201: warnings writes the full source line instead of the truncated one The truncated object is meant to be written instead. --- .../2025-12-26-17-18-18.gh-issue-143201.UbXuX4.rst | 1 + Python/_warnings.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2025-12-26-17-18-18.gh-issue-143201.UbXuX4.rst diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-12-26-17-18-18.gh-issue-143201.UbXuX4.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-12-26-17-18-18.gh-issue-143201.UbXuX4.rst new file mode 100644 index 000000000000000..14ec47fa432e9f2 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-12-26-17-18-18.gh-issue-143201.UbXuX4.rst @@ -0,0 +1 @@ +Print out the truncated line, not the raw sourceline. diff --git a/Python/_warnings.c b/Python/_warnings.c index 86eae5deb859691..3120050df1e2bd2 100644 --- a/Python/_warnings.c +++ b/Python/_warnings.c @@ -716,7 +716,7 @@ show_warning(PyThreadState *tstate, PyObject *filename, int lineno, if (truncated == NULL) goto error; - PyFile_WriteObject(sourceline, f_stderr, Py_PRINT_RAW); + PyFile_WriteObject(truncated, f_stderr, Py_PRINT_RAW); Py_DECREF(truncated); PyFile_WriteString("\n", f_stderr); } From 83bb23f1b01285425f789a0e933bc054bc567f7d Mon Sep 17 00:00:00 2001 From: Cody Maloney Date: Thu, 5 Nov 2026 13:40:16 -0800 Subject: [PATCH 2/3] gh-143201: Indent the dedented source line and add a test Write the two-space indent before the stripped source line, matching _Py_DisplaySourceLine() and the Python implementation, and test the C show_warning() fallback with a loader-provided indented source line. Co-Authored-By: Claude Opus 5.5 --- Lib/test/test_warnings/__init__.py | 15 +++++++++++++++ ...2025-12-26-17-18-18.gh-issue-143201.UbXuX4.rst | 3 ++- Python/_warnings.c | 12 ++++++++---- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/Lib/test/test_warnings/__init__.py b/Lib/test/test_warnings/__init__.py index bfb43025de11405..521d2f64583720a 100644 --- a/Lib/test/test_warnings/__init__.py +++ b/Lib/test/test_warnings/__init__.py @@ -1109,6 +1109,21 @@ def test_showwarnmsg_missing(self): self.module._showwarnmsg = show self.assertIn(text, result) + @support.cpython_only + def test_showwarnmsg_missing_source_line(self): + # gh-143201: the C fallback must strip the source line like Python. + lineno = sys._getframe().f_lineno + with self.module.catch_warnings(), \ + support.swap_attr(self.module, '_showwarnmsg', None), \ + support.captured_stderr() as stream: + self.module.simplefilter("always") + del self.module._showwarnmsg # use the C fallback + self.module.warn_explicit('eggs', UserWarning, __file__, lineno, + module_globals=globals()) + self.assertEqual(stream.getvalue(), py_warnings.formatwarning( + 'eggs', UserWarning, __file__, lineno, + linecache.getline(__file__, lineno))) + def test_showwarning_not_callable(self): orig = self.module.showwarning try: diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-12-26-17-18-18.gh-issue-143201.UbXuX4.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-12-26-17-18-18.gh-issue-143201.UbXuX4.rst index 14ec47fa432e9f2..b2d25a6dc821a98 100644 --- a/Misc/NEWS.d/next/Core_and_Builtins/2025-12-26-17-18-18.gh-issue-143201.UbXuX4.rst +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-12-26-17-18-18.gh-issue-143201.UbXuX4.rst @@ -1 +1,2 @@ -Print out the truncated line, not the raw sourceline. +Fix the C implementation of :mod:`warnings` to strip the indentation of the +source line like the Python implementation. diff --git a/Python/_warnings.c b/Python/_warnings.c index 3120050df1e2bd2..209f5103aa7d765 100644 --- a/Python/_warnings.c +++ b/Python/_warnings.c @@ -666,6 +666,7 @@ show_warning(PyThreadState *tstate, PyObject *filename, int lineno, { PyObject *f_stderr = NULL; PyObject *name; + PyObject *truncated = NULL; char lineno_str[128]; PyOS_snprintf(lineno_str, sizeof(lineno_str), ":%d: ", lineno); @@ -701,7 +702,6 @@ show_warning(PyThreadState *tstate, PyObject *filename, int lineno, const void *data; Py_ssize_t i, len; Py_UCS4 ch; - PyObject *truncated; kind = PyUnicode_KIND(sourceline); data = PyUnicode_DATA(sourceline); @@ -716,9 +716,12 @@ show_warning(PyThreadState *tstate, PyObject *filename, int lineno, if (truncated == NULL) goto error; - PyFile_WriteObject(truncated, f_stderr, Py_PRINT_RAW); - Py_DECREF(truncated); - PyFile_WriteString("\n", f_stderr); + if (PyFile_WriteString(" ", f_stderr) < 0) + goto error; + if (PyFile_WriteObject(truncated, f_stderr, Py_PRINT_RAW) < 0) + goto error; + if (PyFile_WriteString("\n", f_stderr) < 0) + goto error; } else { _Py_DisplaySourceLine(f_stderr, filename, lineno, 2, NULL, NULL); @@ -727,6 +730,7 @@ show_warning(PyThreadState *tstate, PyObject *filename, int lineno, error: Py_XDECREF(f_stderr); Py_XDECREF(name); + Py_XDECREF(truncated); PyErr_Clear(); } From 0e78aafc8f9c443d16ab40c837bb97411feed1c9 Mon Sep 17 00:00:00 2001 From: Cody Maloney Date: Fri, 6 Nov 2026 00:18:14 -0800 Subject: [PATCH 3/3] Use braces for new if statements (PEP 7) Co-Authored-By: Claude Opus 5.5 --- Python/_warnings.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Python/_warnings.c b/Python/_warnings.c index 209f5103aa7d765..58196c5ec646903 100644 --- a/Python/_warnings.c +++ b/Python/_warnings.c @@ -716,12 +716,15 @@ show_warning(PyThreadState *tstate, PyObject *filename, int lineno, if (truncated == NULL) goto error; - if (PyFile_WriteString(" ", f_stderr) < 0) + if (PyFile_WriteString(" ", f_stderr) < 0) { goto error; - if (PyFile_WriteObject(truncated, f_stderr, Py_PRINT_RAW) < 0) + } + if (PyFile_WriteObject(truncated, f_stderr, Py_PRINT_RAW) < 0) { goto error; - if (PyFile_WriteString("\n", f_stderr) < 0) + } + if (PyFile_WriteString("\n", f_stderr) < 0) { goto error; + } } else { _Py_DisplaySourceLine(f_stderr, filename, lineno, 2, NULL, NULL);