summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorxdegaye <xdegaye@gmail.com>2017-10-23 16:08:41 (GMT)
committerGitHub <noreply@github.com>2017-10-23 16:08:41 (GMT)
commit66caacf2f0d6213b049a3097556e28e30440b900 (patch)
tree8485c0ccc79d52485f59529370bd71d30be798c6
parent4ffd4653a7ec9c97775472276cf5e159e2366bb2 (diff)
downloadcpython-66caacf2f0d6213b049a3097556e28e30440b900.zip
cpython-66caacf2f0d6213b049a3097556e28e30440b900.tar.gz
cpython-66caacf2f0d6213b049a3097556e28e30440b900.tar.bz2
bpo-30817: Fix PyErr_PrintEx() when no memory (#2526)
-rw-r--r--Lib/test/test_exceptions.py19
-rw-r--r--Misc/NEWS.d/next/Core and Builtins/2017-07-01-15-11-13.bpo-30817.j7ZvN_.rst2
-rw-r--r--Python/pythonrun.c12
3 files changed, 29 insertions, 4 deletions
diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py
index ad4bc09..cef8d44 100644
--- a/Lib/test/test_exceptions.py
+++ b/Lib/test/test_exceptions.py
@@ -10,7 +10,7 @@ import errno
from test.support import (TESTFN, captured_stderr, check_impl_detail,
check_warnings, cpython_only, gc_collect, run_unittest,
- no_tracing, unlink, import_module)
+ no_tracing, unlink, import_module, script_helper)
class NaiveException(Exception):
def __init__(self, x):
@@ -1097,6 +1097,23 @@ class ExceptionTests(unittest.TestCase):
self.assertIn("test message", report)
self.assertTrue(report.endswith("\n"))
+ @cpython_only
+ def test_memory_error_in_PyErr_PrintEx(self):
+ code = """if 1:
+ import _testcapi
+ class C(): pass
+ _testcapi.set_nomemory(0, %d)
+ C()
+ """
+
+ # Issue #30817: Abort in PyErr_PrintEx() when no memory.
+ # Span a large range of tests as the CPython code always evolves with
+ # changes that add or remove memory allocations.
+ for i in range(1, 20):
+ rc, out, err = script_helper.assert_python_failure("-c", code % i)
+ self.assertIn(rc, (1, 120))
+ self.assertIn(b'MemoryError', err)
+
def test_yield_in_nested_try_excepts(self):
#Issue #25612
class MainError(Exception):
diff --git a/Misc/NEWS.d/next/Core and Builtins/2017-07-01-15-11-13.bpo-30817.j7ZvN_.rst b/Misc/NEWS.d/next/Core and Builtins/2017-07-01-15-11-13.bpo-30817.j7ZvN_.rst
new file mode 100644
index 0000000..f50aeef
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2017-07-01-15-11-13.bpo-30817.j7ZvN_.rst
@@ -0,0 +1,2 @@
+`PyErr_PrintEx()` clears now the ignored exception that may be raised by
+`_PySys_SetObjectId()`, for example when no memory.
diff --git a/Python/pythonrun.c b/Python/pythonrun.c
index 25e2da4..17ec182 100644
--- a/Python/pythonrun.c
+++ b/Python/pythonrun.c
@@ -630,9 +630,15 @@ PyErr_PrintEx(int set_sys_last_vars)
return;
/* Now we know v != NULL too */
if (set_sys_last_vars) {
- _PySys_SetObjectId(&PyId_last_type, exception);
- _PySys_SetObjectId(&PyId_last_value, v);
- _PySys_SetObjectId(&PyId_last_traceback, tb);
+ if (_PySys_SetObjectId(&PyId_last_type, exception) < 0) {
+ PyErr_Clear();
+ }
+ if (_PySys_SetObjectId(&PyId_last_value, v) < 0) {
+ PyErr_Clear();
+ }
+ if (_PySys_SetObjectId(&PyId_last_traceback, tb) < 0) {
+ PyErr_Clear();
+ }
}
hook = _PySys_GetObjectId(&PyId_excepthook);
if (hook) {