]> granicus.if.org Git - python/commitdiff
Issue #25677: Correct syntax error caret for indented blocks.
authorMartin Panter <vadmium+py@gmail.com>
Sun, 11 Dec 2016 00:18:36 +0000 (00:18 +0000)
committerMartin Panter <vadmium+py@gmail.com>
Sun, 11 Dec 2016 00:18:36 +0000 (00:18 +0000)
Based on patch by Michael Layzell.

Lib/test/test_cmd_line_script.py
Misc/ACKS
Misc/NEWS
Python/errors.c
Python/pythonrun.c

index befe0e45d1452a1f884d672e596a02d3733679b1..919f3616c5b089d462b1eed9cbeafdd7f140ed2b 100644 (file)
@@ -10,6 +10,7 @@ import os
 import os.path
 import py_compile
 import subprocess
+import io
 
 import textwrap
 from test import support
@@ -540,6 +541,38 @@ class CmdLineTest(unittest.TestCase):
             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)
index a9cd72e660480672abcf339d063a1626508394c8..e4b86390055e85baed1025290c9b63f256d67976 100644 (file)
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -840,6 +840,7 @@ Julia Lawall
 Chris Lawrence
 Mark Lawrence
 Chris Laws
+Michael Layzell
 Michael Lazar
 Brian Leair
 Mathieu Leduc-Hamel
index 13e9e6d53dab8f94f8da0b0cb30ed48097a9cbf8..f613d0deb992f236f4d9e00c170d70a4ee3d3e94 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,9 @@ Release date: TBA
 Core and Builtins
 -----------------
 
+- Issue #25677: Correct the positioning of the syntax error caret for
+  indented blocks.  Based on patch by Michael Layzell.
+
 - Issue #29000: Fixed bytes formatting of octals with zero padding in alternate
   form.
 
index ebfb3fdf24025648f36d9e24f3818fec79cefa80..b820722dfa1b322568ea221e7f4c3b6f87090d25 100644 (file)
@@ -1094,11 +1094,8 @@ err_programtext(FILE *fp, int lineno)
     }
     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;
index 72b6c9b0608b43438266876d31b4552df3d62586..90cb2de27ca23449b370e1def594504954ffdaf9 100644 (file)
@@ -528,7 +528,7 @@ print_error_text(PyObject *f, int offset, PyObject *text_obj)
             offset -= (int)(nl+1-text);
             text = nl+1;
         }
-        while (*text == ' ' || *text == '\t') {
+        while (*text == ' ' || *text == '\t' || *text == '\f') {
             text++;
             offset--;
         }