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