From: Martin Panter Date: 1481415516 0 Issue #25677: Correct syntax error caret for indented blocks. Based on patch by Michael Layzell. diff -r b396a2c97871 Lib/test/test_cmd_line_script.py --- a/Lib/test/test_cmd_line_script.py Sat Dec 10 14:15:22 2016 -0800 +++ b/Lib/test/test_cmd_line_script.py Sun Dec 11 00:27:43 2016 +0000 @@ -10,6 +10,7 @@ import os.path import py_compile import subprocess +import io import textwrap from test import support @@ -539,6 +540,38 @@ text = stderr.decode('ascii') self.assertEqual(text, "some text") + def test_syntaxerror_unindented_caret_position(self): + script = "1 + 1 = 2\n" + with support.temp_dir() as script_dir: + script_name = _make_test_script(script_dir, 'script', script) + exitcode, stdout, stderr = assert_python_failure(script_name) + text = io.TextIOWrapper(io.BytesIO(stderr), 'ascii').read() + # Confirm that the caret is located under the first 1 character + self.assertIn("\n 1 + 1 = 2\n ^", text) + + def test_syntaxerror_indented_caret_position(self): + script = textwrap.dedent("""\ + if True: + 1 + 1 = 2 + """) + with support.temp_dir() as script_dir: + script_name = _make_test_script(script_dir, 'script', script) + exitcode, stdout, stderr = assert_python_failure(script_name) + text = io.TextIOWrapper(io.BytesIO(stderr), 'ascii').read() + # Confirm that the caret is located under the first 1 character + self.assertIn("\n 1 + 1 = 2\n ^", text) + + # Try the same with a form feed at the start of the indented line + script = ( + "if True:\n" + "\f 1 + 1 = 2\n" + ) + script_name = _make_test_script(script_dir, "script", script) + exitcode, stdout, stderr = assert_python_failure(script_name) + text = io.TextIOWrapper(io.BytesIO(stderr), "ascii").read() + self.assertNotIn("\f", text) + self.assertIn("\n 1 + 1 = 2\n ^", text) + def test_main(): support.run_unittest(CmdLineTest) diff -r b396a2c97871 Misc/ACKS --- a/Misc/ACKS Sat Dec 10 14:15:22 2016 -0800 +++ b/Misc/ACKS Sun Dec 11 00:27:43 2016 +0000 @@ -851,6 +851,7 @@ Chris Lawrence Mark Lawrence Chris Laws +Michael Layzell Michael Lazar Brian Leair Mathieu Leduc-Hamel diff -r b396a2c97871 Misc/NEWS --- a/Misc/NEWS Sat Dec 10 14:15:22 2016 -0800 +++ b/Misc/NEWS Sun Dec 11 00:27:43 2016 +0000 @@ -10,6 +10,9 @@ Core and Builtins ----------------- +- Issue #25677: Correct the positioning of the syntax error caret for + indented blocks. Based on patch by Michael Layzell. + - Issue #28918: Fix the cross compilation of xxlimited when Python has been built with Py_DEBUG defined. diff -r b396a2c97871 Python/errors.c --- a/Python/errors.c Sat Dec 10 14:15:22 2016 -0800 +++ b/Python/errors.c Sun Dec 11 00:27:43 2016 +0000 @@ -1142,11 +1142,8 @@ } fclose(fp); if (i == lineno) { - char *p = linebuf; PyObject *res; - while (*p == ' ' || *p == '\t' || *p == '\014') - p++; - res = PyUnicode_FromString(p); + res = PyUnicode_FromString(linebuf); if (res == NULL) PyErr_Clear(); return res; diff -r b396a2c97871 Python/pythonrun.c --- a/Python/pythonrun.c Sat Dec 10 14:15:22 2016 -0800 +++ b/Python/pythonrun.c Sun Dec 11 00:27:43 2016 +0000 @@ -528,7 +528,7 @@ offset -= (int)(nl+1-text); text = nl+1; } - while (*text == ' ' || *text == '\t') { + while (*text == ' ' || *text == '\t' || *text == '\f') { text++; offset--; }