mirror of
https://github.com/python/cpython.git
synced 2025-12-31 04:23:37 +00:00
[3.14] gh-142737: Handle lost io.open in _Py_FindSourceFile (GH-142747) (GH-142773)
gh-142737: Handle lost `io.open` in `_Py_FindSourceFile` (GH-142747)
(cherry picked from commit f277781bba)
Co-authored-by: Bartosz Sławecki <bartosz@ilikepython.com>
This commit is contained in:
parent
88ac9956cd
commit
b9cbdde80d
4 changed files with 35 additions and 1 deletions
|
|
@ -18,7 +18,7 @@
|
|||
from test.support import (Error, captured_output, cpython_only, ALWAYS_EQ,
|
||||
requires_debug_ranges, has_no_debug_ranges,
|
||||
requires_subprocess)
|
||||
from test.support.os_helper import TESTFN, unlink
|
||||
from test.support.os_helper import TESTFN, temp_dir, unlink
|
||||
from test.support.script_helper import assert_python_ok, assert_python_failure, make_script
|
||||
from test.support.import_helper import forget
|
||||
from test.support import force_not_colorized, force_not_colorized_test_class
|
||||
|
|
@ -504,6 +504,33 @@ def __del__(self):
|
|||
b'ZeroDivisionError: division by zero']
|
||||
self.assertEqual(stderr.splitlines(), expected)
|
||||
|
||||
@cpython_only
|
||||
def test_lost_io_open(self):
|
||||
# GH-142737: Display the traceback even if io.open is lost
|
||||
crasher = textwrap.dedent("""\
|
||||
import io
|
||||
import traceback
|
||||
# Trigger fallback mode
|
||||
traceback._print_exception_bltin = None
|
||||
del io.open
|
||||
raise RuntimeError("should not crash")
|
||||
""")
|
||||
|
||||
# Create a temporary script to exercise _Py_FindSourceFile
|
||||
with temp_dir() as script_dir:
|
||||
script = make_script(
|
||||
script_dir=script_dir,
|
||||
script_basename='tb_test_no_io_open',
|
||||
source=crasher)
|
||||
rc, stdout, stderr = assert_python_failure(script)
|
||||
|
||||
self.assertEqual(rc, 1) # Make sure it's not a crash
|
||||
|
||||
expected = [b'Traceback (most recent call last):',
|
||||
f' File "{script}", line 6, in <module>'.encode(),
|
||||
b'RuntimeError: should not crash']
|
||||
self.assertEqual(stderr.splitlines(), expected)
|
||||
|
||||
def test_print_exception(self):
|
||||
output = StringIO()
|
||||
traceback.print_exception(
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
Tracebacks will be displayed in fallback mode even if :func:`io.open` is lost.
|
||||
Previously, this would crash the interpreter.
|
||||
Patch by Bartosz Sławecki.
|
||||
|
|
@ -726,6 +726,7 @@ _PyObject_CallMethodId(PyObject *obj, _Py_Identifier *name,
|
|||
PyObject * _PyObject_CallMethodFormat(PyThreadState *tstate, PyObject *callable,
|
||||
const char *format, ...)
|
||||
{
|
||||
assert(callable != NULL);
|
||||
va_list va;
|
||||
va_start(va, format);
|
||||
PyObject *retval = callmethod(tstate, callable, format, va);
|
||||
|
|
|
|||
|
|
@ -416,6 +416,9 @@ _Py_FindSourceFile(PyObject *filename, char* namebuf, size_t namelen, PyObject *
|
|||
npath = PyList_Size(syspath);
|
||||
|
||||
open = PyObject_GetAttr(io, &_Py_ID(open));
|
||||
if (open == NULL) {
|
||||
goto error;
|
||||
}
|
||||
for (i = 0; i < npath; i++) {
|
||||
v = PyList_GetItem(syspath, i);
|
||||
if (v == NULL) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue