[Python-checkins] cpython: Close #20500: Don't trigger PyObject_Str assertion at shutdown

nick.coghlan python-checkins at python.org
Sun Feb 9 01:47:12 CET 2014


http://hg.python.org/cpython/rev/e7708864a8d5
changeset:   89076:e7708864a8d5
user:        Nick Coghlan <ncoghlan at gmail.com>
date:        Sun Feb 09 10:43:21 2014 +1000
summary:
  Close #20500: Don't trigger PyObject_Str assertion at shutdown

files:
  Lib/test/test_cmd_line_script.py |  18 ++++++++++++++++++
  Misc/NEWS                        |   5 ++++-
  Objects/object.c                 |   2 +-
  Python/pythonrun.c               |   5 +++++
  4 files changed, 28 insertions(+), 2 deletions(-)


diff --git a/Lib/test/test_cmd_line_script.py b/Lib/test/test_cmd_line_script.py
--- a/Lib/test/test_cmd_line_script.py
+++ b/Lib/test/test_cmd_line_script.py
@@ -405,6 +405,24 @@
             'stdout=%r stderr=%r' % (stdout, stderr))
         self.assertEqual(0, rc)
 
+    def test_issue20500_exit_with_exception_value(self):
+        script = textwrap.dedent("""\
+            import sys
+            error = None
+            try:
+                raise ValueError('some text')
+            except ValueError as err:
+                error = err
+
+            if error:
+                sys.exit(error)
+            """)
+        with temp_dir() as script_dir:
+            script_name = _make_test_script(script_dir, 'script', script)
+            exitcode, stdout, stderr = assert_python_failure(script_name)
+            text = stderr.decode('ascii')
+            self.assertEqual(text, "some text")
+
 
 def test_main():
     support.run_unittest(CmdLineTest)
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,7 +10,10 @@
 Core and Builtins
 -----------------
 
-- Issue #20538: UTF-7 incremental decoder produced inconsistant string when
+- Issue #20500: Displaying an exception at interpreter shutdown no longer
+  risks triggering an assertion failure in PyObject_Str.
+
+- Issue #20538: UTF-7 incremental decoder produced inconsistent string when
   input was truncated in BASE64 section.
 
 - Issue #20404: io.TextIOWrapper (and hence the open() builtin) now uses the
diff --git a/Objects/object.c b/Objects/object.c
--- a/Objects/object.c
+++ b/Objects/object.c
@@ -508,7 +508,7 @@
 #ifdef Py_DEBUG
     /* PyObject_Str() must not be called with an exception set,
        because it may clear it (directly or indirectly) and so the
-       caller looses its exception */
+       caller loses its exception */
     assert(!PyErr_Occurred());
 #endif
 
diff --git a/Python/pythonrun.c b/Python/pythonrun.c
--- a/Python/pythonrun.c
+++ b/Python/pythonrun.c
@@ -1792,6 +1792,11 @@
         exitcode = (int)PyLong_AsLong(value);
     else {
         PyObject *sys_stderr = _PySys_GetObjectId(&PyId_stderr);
+        /* We clear the exception here to avoid triggering the assertion
+         * in PyObject_Str that ensures it won't silently lose exception
+         * details.
+         */
+        PyErr_Clear();
         if (sys_stderr != NULL && sys_stderr != Py_None) {
             PyFile_WriteObject(value, sys_stderr, Py_PRINT_RAW);
         } else {

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list