mirror of https://github.com/python/cpython
[3.13] gh-119049: Fix incorrect display of warning which is constructed by C API (GH-119063) (GH-119106)
The source line was not displayed if the warnings module had not yet
been imported.
(cherry picked from commit 100c7ab00a
)
Co-authored-by: Kirill Podoprigora <kirill.bast9@mail.ru>
This commit is contained in:
parent
ada4ad0e24
commit
ced71d39cf
|
@ -3,11 +3,12 @@ import os
|
|||
import re
|
||||
import sys
|
||||
import unittest
|
||||
import textwrap
|
||||
|
||||
from test import support
|
||||
from test.support import import_helper
|
||||
from test.support.os_helper import TESTFN, TESTFN_UNDECODABLE
|
||||
from test.support.script_helper import assert_python_failure
|
||||
from test.support.script_helper import assert_python_failure, assert_python_ok
|
||||
from test.support.testcase import ExceptionIsLikeMixin
|
||||
|
||||
from .test_misc import decode_stderr
|
||||
|
@ -68,6 +69,47 @@ class Test_Exceptions(unittest.TestCase):
|
|||
else:
|
||||
self.assertTrue(False)
|
||||
|
||||
def test_warn_with_stacklevel(self):
|
||||
code = textwrap.dedent('''\
|
||||
import _testcapi
|
||||
|
||||
def foo():
|
||||
_testcapi.function_set_warning()
|
||||
|
||||
foo() # line 6
|
||||
|
||||
|
||||
foo() # line 9
|
||||
''')
|
||||
proc = assert_python_ok("-c", code)
|
||||
warnings = proc.err.splitlines()
|
||||
self.assertEqual(warnings, [
|
||||
b'<string>:6: RuntimeWarning: Testing PyErr_WarnEx',
|
||||
b' foo() # line 6',
|
||||
b'<string>:9: RuntimeWarning: Testing PyErr_WarnEx',
|
||||
b' foo() # line 9',
|
||||
])
|
||||
|
||||
def test_warn_during_finalization(self):
|
||||
code = textwrap.dedent('''\
|
||||
import _testcapi
|
||||
|
||||
class Foo:
|
||||
def foo(self):
|
||||
_testcapi.function_set_warning()
|
||||
def __del__(self):
|
||||
self.foo()
|
||||
|
||||
ref = Foo()
|
||||
''')
|
||||
proc = assert_python_ok("-c", code)
|
||||
warnings = proc.err.splitlines()
|
||||
# Due to the finalization of the interpreter, the source will be ommited
|
||||
# because the ``warnings`` module cannot be imported at this time
|
||||
self.assertEqual(warnings, [
|
||||
b'<string>:7: RuntimeWarning: Testing PyErr_WarnEx',
|
||||
])
|
||||
|
||||
|
||||
class Test_FatalError(unittest.TestCase):
|
||||
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
Fix displaying the source line for warnings created by the C API if the
|
||||
:mod:`warnings` module had not yet been imported.
|
|
@ -3303,6 +3303,15 @@ failed:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
function_set_warning(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
|
||||
{
|
||||
if (PyErr_WarnEx(PyExc_RuntimeWarning, "Testing PyErr_WarnEx", 2)) {
|
||||
return NULL;
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyMethodDef TestMethods[] = {
|
||||
{"set_errno", set_errno, METH_VARARGS},
|
||||
{"test_config", test_config, METH_NOARGS},
|
||||
|
@ -3444,6 +3453,7 @@ static PyMethodDef TestMethods[] = {
|
|||
{"function_set_closure", function_set_closure, METH_VARARGS, NULL},
|
||||
{"check_pyimport_addmodule", check_pyimport_addmodule, METH_VARARGS},
|
||||
{"test_weakref_capi", test_weakref_capi, METH_NOARGS},
|
||||
{"function_set_warning", function_set_warning, METH_NOARGS},
|
||||
{NULL, NULL} /* sentinel */
|
||||
};
|
||||
|
||||
|
|
|
@ -569,10 +569,9 @@ call_show_warning(PyThreadState *tstate, PyObject *category,
|
|||
PyObject *show_fn, *msg, *res, *warnmsg_cls = NULL;
|
||||
PyInterpreterState *interp = tstate->interp;
|
||||
|
||||
/* If the source parameter is set, try to get the Python implementation.
|
||||
The Python implementation is able to log the traceback where the source
|
||||
/* The Python implementation is able to log the traceback where the source
|
||||
was allocated, whereas the C implementation doesn't. */
|
||||
show_fn = GET_WARNINGS_ATTR(interp, _showwarnmsg, source != NULL);
|
||||
show_fn = GET_WARNINGS_ATTR(interp, _showwarnmsg, 1);
|
||||
if (show_fn == NULL) {
|
||||
if (PyErr_Occurred())
|
||||
return -1;
|
||||
|
|
Loading…
Reference in New Issue