From: Benjamin Peterson <benjamin@python.org> Date: Sun, 2 Sep 2012 18:23:15 +0000 (-0400) Subject: prevert ast errors from being normalized before ast_error_finish is called (closes... X-Git-Tag: v3.3.1rc1~813^2~121 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2e2c903700991aa9f7e96d7a7fdaed3628dc7e1e;p=python prevert ast errors from being normalized before ast_error_finish is called (closes #15846) --- diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py index e22d4de88b..2887092a7d 100644 --- a/Lib/test/test_ast.py +++ b/Lib/test/test_ast.py @@ -386,6 +386,12 @@ class ASTHelpers_Test(unittest.TestCase): b = compile('foo(1 + 1)', '<unknown>', 'exec', ast.PyCF_ONLY_AST) self.assertEqual(ast.dump(a), ast.dump(b)) + def test_parse_in_error(self): + try: + 1/0 + except Exception: + self.assertRaises(SyntaxError, ast.parse, r"'\U'") + def test_dump(self): node = ast.parse('spam(eggs, "and cheese")') self.assertEqual(ast.dump(node), diff --git a/Misc/NEWS b/Misc/NEWS index 4bb9698ac1..544bf67afb 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,9 @@ What's New in Python 3.2.4 Core and Builtins ----------------- +- Issue #15846: Fix SystemError which happened when using ast.parse in an + exception handler on code with syntax errors. + - Issue #15761: Fix crash when PYTHONEXECUTABLE is set on Mac OS X. - Issue #15801: Make sure mappings passed to '%' formatting are actually diff --git a/Python/ast.c b/Python/ast.c index 6faf5b21a6..3d0e3844b7 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -92,7 +92,15 @@ ast_error(const node *n, const char *errstr) PyObject *u = Py_BuildValue("zii", errstr, LINENO(n), n->n_col_offset); if (!u) return 0; + /* + * Prevent the error from being chained. PyErr_SetObject will normalize the + * exception in order to chain it. ast_error_finish, however, requires the + * error not to be normalized. + */ + PyObject *save = PyThreadState_GET()->exc_value; + PyThreadState_GET()->exc_value = NULL; PyErr_SetObject(PyExc_SyntaxError, u); + PyThreadState_GET()->exc_value = save; Py_DECREF(u); return 0; }