Author: Carl Friedrich Bolz-Tereick <[email protected]>
Branch: py3.6
Changeset: r97369:8cebeebbf0a7
Date: 2019-09-02 21:56 +0200
http://bitbucket.org/pypy/pypy/changeset/8cebeebbf0a7/

Log:    two improvements around the print SyntaxError

        - the old implementation shadowed the much better error messages
        around wrong parentheses that PyPy (and nowadays CPython) has

        - also provide the heuristics for giving a corrected print function
        call that Python 3.6 does

diff --git a/pypy/interpreter/pyparser/test/test_pyparse.py 
b/pypy/interpreter/pyparser/test/test_pyparse.py
--- a/pypy/interpreter/pyparser/test/test_pyparse.py
+++ b/pypy/interpreter/pyparser/test/test_pyparse.py
@@ -392,6 +392,8 @@
     def test_error_print_without_parens(self):
         info = py.test.raises(SyntaxError, self.parse, "print 1")
         assert "Missing parentheses in call to 'print'" in info.value.msg
+        info = py.test.raises(SyntaxError, self.parse, "print 1)")
+        assert "unmatched" in info.value.msg
 
 class TestPythonParserRevDB(TestPythonParser):
     spaceconfig = {"translation.reverse_debugger": True}
diff --git a/pypy/module/exceptions/interp_exceptions.py 
b/pypy/module/exceptions/interp_exceptions.py
--- a/pypy/module/exceptions/interp_exceptions.py
+++ b/pypy/module/exceptions/interp_exceptions.py
@@ -814,6 +814,10 @@
 
     # CPython Issue #21669: Custom error for 'print' & 'exec' as statements
     def _report_missing_parentheses(self, space):
+        if not space.text_w(self.w_msg).startswith("Missing parentheses in 
call to "):
+            # the parser identifies the correct places where the error should
+            # be produced
+            return
         text = space.utf8_w(self.w_text)
         if b'(' in text:
             # Use default error message for any line with an opening paren
@@ -830,7 +834,7 @@
 
     def _check_for_legacy_statements(self, space, text, start):
         # Ignore leading whitespace
-        while start < len(text) and text[start] == u' ':
+        while start < len(text) and text[start] == b' ':
             start += 1
         # Checking against an empty or whitespace-only part of the string
         if start == len(text):
@@ -839,7 +843,7 @@
             text = text[start:]
         # Check for legacy print statements
         if text.startswith(b"print "):
-            self.w_msg = space.newtext("Missing parentheses in call to 
'print'")
+            self._set_legacy_print_statement_msg(space, text)
             return True
         # Check for legacy exec statements
         if text.startswith(b"exec "):
@@ -847,6 +851,22 @@
             return True
         return False
 
+    def _set_legacy_print_statement_msg(self, space, text):
+        text = text[len("print"):]
+        if text.endswith(";"):
+            end = len(text) - 1
+            assert end >= 0
+            text = text[:end]
+        text = text.strip()
+
+        maybe_end = ""
+        if text.endswith(","):
+            maybe_end = " end=\" \""
+
+        self.w_msg = space.newtext(
+            "Missing parentheses in call to 'print'. Did you mean 
print(%s%s)?" % (
+                text, maybe_end))
+
 
 W_SyntaxError.typedef = TypeDef(
     'SyntaxError',
diff --git a/pypy/module/exceptions/test/test_exc.py 
b/pypy/module/exceptions/test/test_exc.py
--- a/pypy/module/exceptions/test/test_exc.py
+++ b/pypy/module/exceptions/test/test_exc.py
@@ -443,6 +443,25 @@
                 assert (custom_msg not in exc.value.msg) == (
                     ('print (' in source or 'exec (' in source))
 
+    def test_bug_print_heuristic_shadows_better_message(self):
+        def exec_(s): exec(s)
+        exc = raises(SyntaxError, exec_, "print [)")
+        assert "closing parenthesis ')' does not match opening parenthesis 
'['" in exc.value.msg
+
+    def test_print_suggestions(self):
+        def exec_(s): exec(s)
+        def check(s, error):
+            exc = raises(SyntaxError, exec_, s)
+            print(exc.value.msg)
+            assert exc.value.msg == error
+
+        check(
+            "print 1",
+            "Missing parentheses in call to 'print'. Did you mean print(1)?")
+        check(
+            "print 1, \t",
+            "Missing parentheses in call to 'print'. Did you mean print(1, 
end=\" \")?")
+
     def test_importerror_kwarg_error(self):
         msg = "'invalid' is an invalid keyword argument for this function"
         exc = raises(TypeError,
@@ -463,3 +482,4 @@
                      'test', path='path', invalid='keyword')
         assert str(exc.value) == msg
 
+
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to