Skip to content

Commit 2f01c56

Browse files
authored
[3.7] bpo-43660: Fix crash when displaying exceptions with custom values for sys.stderr (GH-25075). (GH-25085)
(cherry picked from commit 09b90a0) Co-authored-by: Pablo Galindo <[email protected]>
1 parent 7c2284f commit 2f01c56

File tree

3 files changed

+20
-0
lines changed

3 files changed

+20
-0
lines changed

Lib/test/test_sys.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1292,6 +1292,21 @@ def test_asyncgen_hooks(self):
12921292
self.assertIsNone(cur.firstiter)
12931293
self.assertIsNone(cur.finalizer)
12941294

1295+
def test_changing_sys_stderr_and_removing_reference(self):
1296+
# If the default displayhook doesn't take a strong reference
1297+
# to sys.stderr the following code can crash. See bpo-43660
1298+
# for more details.
1299+
code = textwrap.dedent('''
1300+
import sys
1301+
class MyStderr:
1302+
def write(self, s):
1303+
sys.stderr = None
1304+
sys.stderr = MyStderr()
1305+
1/0
1306+
''')
1307+
rc, out, err = assert_python_failure('-c', code)
1308+
self.assertEqual(out, b"")
1309+
self.assertEqual(err, b"")
12951310

12961311
def test_main():
12971312
test.support.run_unittest(SysModuleTest, SizeofTest)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix crash that happens when replacing ``sys.stderr`` with a callable that
2+
can remove the object while an exception is being printed. Patch by Pablo
3+
Galindo.

Python/pythonrun.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -932,7 +932,9 @@ PyErr_Display(PyObject *exception, PyObject *value, PyObject *tb)
932932
seen = PySet_New(NULL);
933933
if (seen == NULL)
934934
PyErr_Clear();
935+
Py_INCREF(f);
935936
print_exception_recursive(f, value, seen);
937+
Py_DECREF(f);
936938
Py_XDECREF(seen);
937939
}
938940
}

0 commit comments

Comments
 (0)