mirror of https://github.com/python/cpython
gh-121804: always show error location for SyntaxError's in basic repl (#123202)
This commit is contained in:
parent
ef9d54703f
commit
6822cb23c6
|
@ -187,6 +187,19 @@ class TestInteractiveInterpreter(unittest.TestCase):
|
|||
]
|
||||
self.assertEqual(traceback_lines, expected_lines)
|
||||
|
||||
def test_runsource_show_syntax_error_location(self):
|
||||
user_input = dedent("""def f(x, x): ...
|
||||
""")
|
||||
p = spawn_repl()
|
||||
p.stdin.write(user_input)
|
||||
output = kill_python(p)
|
||||
expected_lines = [
|
||||
' def f(x, x): ...',
|
||||
' ^',
|
||||
"SyntaxError: duplicate argument 'x' in function definition"
|
||||
]
|
||||
self.assertEqual(output.splitlines()[4:-1], expected_lines)
|
||||
|
||||
def test_interactive_source_is_in_linecache(self):
|
||||
user_input = dedent("""
|
||||
def foo(x):
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
Correctly show error locations when a :exc:`SyntaxError` is raised
|
||||
in the basic REPL. Patch by Sergey B Kirpichev.
|
|
@ -280,11 +280,42 @@ PyRun_InteractiveOneObjectEx(FILE *fp, PyObject *filename,
|
|||
PyObject *main_dict = PyModule_GetDict(main_module); // borrowed ref
|
||||
|
||||
PyObject *res = run_mod(mod, filename, main_dict, main_dict, flags, arena, interactive_src, 1);
|
||||
Py_INCREF(interactive_src);
|
||||
_PyArena_Free(arena);
|
||||
Py_DECREF(main_module);
|
||||
if (res == NULL) {
|
||||
PyThreadState *tstate = _PyThreadState_GET();
|
||||
PyObject *exc = _PyErr_GetRaisedException(tstate);
|
||||
if (PyType_IsSubtype(Py_TYPE(exc),
|
||||
(PyTypeObject *) PyExc_SyntaxError))
|
||||
{
|
||||
/* fix "text" attribute */
|
||||
assert(interactive_src != NULL);
|
||||
PyObject *xs = PyUnicode_Splitlines(interactive_src, 1);
|
||||
if (xs == NULL) {
|
||||
goto error;
|
||||
}
|
||||
PyObject *exc_lineno = PyObject_GetAttr(exc, &_Py_ID(lineno));
|
||||
if (exc_lineno == NULL) {
|
||||
Py_DECREF(xs);
|
||||
goto error;
|
||||
}
|
||||
int n = PyLong_AsInt(exc_lineno);
|
||||
Py_DECREF(exc_lineno);
|
||||
if (n <= 0 || n > PyList_GET_SIZE(xs)) {
|
||||
Py_DECREF(xs);
|
||||
goto error;
|
||||
}
|
||||
PyObject *line = PyList_GET_ITEM(xs, n - 1);
|
||||
PyObject_SetAttr(exc, &_Py_ID(text), line);
|
||||
Py_DECREF(xs);
|
||||
}
|
||||
error:
|
||||
Py_DECREF(interactive_src);
|
||||
_PyErr_SetRaisedException(tstate, exc);
|
||||
return -1;
|
||||
}
|
||||
Py_DECREF(interactive_src);
|
||||
Py_DECREF(res);
|
||||
|
||||
flush_io();
|
||||
|
|
Loading…
Reference in New Issue