Skip to content

Commit 09b90a0

Browse files
authored
bpo-43660: Fix crash when displaying exceptions with custom values for sys.stderr (GH-25075)
1 parent c8b5738 commit 09b90a0

File tree

3 files changed

+20
-1
lines changed

3 files changed

+20
-1
lines changed

Lib/test/test_sys.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1512,6 +1512,21 @@ def test_asyncgen_hooks(self):
15121512
self.assertIsNone(cur.firstiter)
15131513
self.assertIsNone(cur.finalizer)
15141514

1515+
def test_changing_sys_stderr_and_removing_reference(self):
1516+
# If the default displayhook doesn't take a strong reference
1517+
# to sys.stderr the following code can crash. See bpo-43660
1518+
# for more details.
1519+
code = textwrap.dedent('''
1520+
import sys
1521+
class MyStderr:
1522+
def write(self, s):
1523+
sys.stderr = None
1524+
sys.stderr = MyStderr()
1525+
1/0
1526+
''')
1527+
rc, out, err = assert_python_failure('-c', code)
1528+
self.assertEqual(out, b"")
1529+
self.assertEqual(err, b"")
15151530

15161531
if __name__ == "__main__":
15171532
unittest.main()
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 & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1082,8 +1082,9 @@ PyErr_Display(PyObject *exception, PyObject *value, PyObject *tb)
10821082
if (file == Py_None) {
10831083
return;
10841084
}
1085-
1085+
Py_INCREF(file);
10861086
_PyErr_Display(file, exception, value, tb);
1087+
Py_DECREF(file);
10871088
}
10881089

10891090
PyObject *

0 commit comments

Comments
 (0)