https://github.com/python/cpython/commit/6822cb23c62032381971d8a47fd41d1e98710a8c
commit: 6822cb23c62032381971d8a47fd41d1e98710a8c
branch: main
author: Sergey B Kirpichev <[email protected]>
committer: pablogsal <[email protected]>
date: 2024-09-03T12:37:29Z
summary:
gh-121804: always show error location for SyntaxError's in basic repl (#123202)
files:
A Misc/NEWS.d/next/Core and
Builtins/2024-08-21-15-22-53.gh-issue-121804.r5K3PS.rst
M Lib/test/test_repl.py
M Python/pythonrun.c
diff --git a/Lib/test/test_repl.py b/Lib/test/test_repl.py
index 0b938623856e4f..363808cb444322 100644
--- a/Lib/test/test_repl.py
+++ b/Lib/test/test_repl.py
@@ -187,6 +187,19 @@ def foo(x):
]
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):
diff --git a/Misc/NEWS.d/next/Core and
Builtins/2024-08-21-15-22-53.gh-issue-121804.r5K3PS.rst b/Misc/NEWS.d/next/Core
and Builtins/2024-08-21-15-22-53.gh-issue-121804.r5K3PS.rst
new file mode 100644
index 00000000000000..ce96c316923ce5
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and
Builtins/2024-08-21-15-22-53.gh-issue-121804.r5K3PS.rst
@@ -0,0 +1,2 @@
+Correctly show error locations when a :exc:`SyntaxError` is raised
+in the basic REPL. Patch by Sergey B Kirpichev.
diff --git a/Python/pythonrun.c b/Python/pythonrun.c
index ce7f194e929c9c..b67597113ead45 100644
--- a/Python/pythonrun.c
+++ b/Python/pythonrun.c
@@ -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();
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]