Skip to content

Commit ff4715a

Browse files
bpo-43660: Fix crash when displaying exceptions with custom values for sys.stderr (GH-25075) (GH-25083)
(cherry picked from commit 09b90a0) Co-authored-by: Pablo Galindo <Pablogsal@gmail.com> Co-authored-by: Pablo Galindo <Pablogsal@gmail.com>
1 parent acb5849 commit ff4715a

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
@@ -1417,6 +1417,21 @@ def test_asyncgen_hooks(self):
14171417
self.assertIsNone(cur.firstiter)
14181418
self.assertIsNone(cur.finalizer)
14191419

1420+
def test_changing_sys_stderr_and_removing_reference(self):
1421+
# If the default displayhook doesn't take a strong reference
1422+
# to sys.stderr the following code can crash. See bpo-43660
1423+
# for more details.
1424+
code = textwrap.dedent('''
1425+
import sys
1426+
class MyStderr:
1427+
def write(self, s):
1428+
sys.stderr = None
1429+
sys.stderr = MyStderr()
1430+
1/0
1431+
''')
1432+
rc, out, err = assert_python_failure('-c', code)
1433+
self.assertEqual(out, b"")
1434+
self.assertEqual(err, b"")
14201435

14211436
if __name__ == "__main__":
14221437
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
@@ -1072,8 +1072,9 @@ PyErr_Display(PyObject *exception, PyObject *value, PyObject *tb)
10721072
if (file == Py_None) {
10731073
return;
10741074
}
1075-
1075+
Py_INCREF(file);
10761076
_PyErr_Display(file, exception, value, tb);
1077+
Py_DECREF(file);
10771078
}
10781079

10791080
PyObject *

0 commit comments

Comments
 (0)