Resolve py2 grammar (alternative to #776) (#1090)
* Resolve use of Python 2 grammar + fix three related test cases
* Simplify ParseCodeToTree with identical semantics
diff --git a/yapf/pytree/pytree_utils.py b/yapf/pytree/pytree_utils.py
index 66a54e6..43ef876 100644
--- a/yapf/pytree/pytree_utils.py
+++ b/yapf/pytree/pytree_utils.py
@@ -84,11 +84,10 @@
# context where a keyword is disallowed).
# It forgets to do the same for 'exec' though. Luckily, Python is amenable to
# monkey-patching.
-_GRAMMAR_FOR_PY3 = pygram.python_grammar_no_print_statement.copy()
-del _GRAMMAR_FOR_PY3.keywords['exec']
-
-_GRAMMAR_FOR_PY2 = pygram.python_grammar.copy()
-del _GRAMMAR_FOR_PY2.keywords['nonlocal']
+# Note that pygram.python_grammar_no_print_and_exec_statement with "_and_exec"
+# will require Python >=3.8.
+_PYTHON_GRAMMAR = pygram.python_grammar_no_print_statement.copy()
+del _PYTHON_GRAMMAR.keywords['exec']
def ParseCodeToTree(code):
@@ -110,24 +109,12 @@
code += os.linesep
try:
- # Try to parse using a Python 3 grammar, which is more permissive (print and
- # exec are not keywords).
- parser_driver = driver.Driver(_GRAMMAR_FOR_PY3, convert=pytree.convert)
+ parser_driver = driver.Driver(_PYTHON_GRAMMAR, convert=pytree.convert)
tree = parser_driver.parse_string(code, debug=False)
except parse.ParseError:
- # Now try to parse using a Python 2 grammar; If this fails, then
- # there's something else wrong with the code.
- try:
- parser_driver = driver.Driver(_GRAMMAR_FOR_PY2, convert=pytree.convert)
- tree = parser_driver.parse_string(code, debug=False)
- except parse.ParseError:
- # Raise a syntax error if the code is invalid python syntax.
- try:
- ast.parse(code)
- except SyntaxError as e:
- raise e
- else:
- raise
+ # Raise a syntax error if the code is invalid python syntax.
+ ast.parse(code)
+ raise
return _WrapEndMarker(tree)
diff --git a/yapftests/pytree_utils_test.py b/yapftests/pytree_utils_test.py
index c175f83..c55f668 100644
--- a/yapftests/pytree_utils_test.py
+++ b/yapftests/pytree_utils_test.py
@@ -63,16 +63,12 @@
self.assertEqual('simple_stmt', pytree_utils.NodeName(tree.children[0]))
def testPrintStatementToTree(self):
- tree = pytree_utils.ParseCodeToTree('print "hello world"\n')
- self.assertEqual('file_input', pytree_utils.NodeName(tree))
- self.assertEqual(2, len(tree.children))
- self.assertEqual('simple_stmt', pytree_utils.NodeName(tree.children[0]))
+ with self.assertRaises(SyntaxError):
+ pytree_utils.ParseCodeToTree('print "hello world"\n')
def testClassNotLocal(self):
- tree = pytree_utils.ParseCodeToTree('class nonlocal: pass\n')
- self.assertEqual('file_input', pytree_utils.NodeName(tree))
- self.assertEqual(2, len(tree.children))
- self.assertEqual('classdef', pytree_utils.NodeName(tree.children[0]))
+ with self.assertRaises(SyntaxError):
+ pytree_utils.ParseCodeToTree('class nonlocal: pass\n')
class InsertNodesBeforeAfterTest(unittest.TestCase):
diff --git a/yapftests/reformatter_buganizer_test.py b/yapftests/reformatter_buganizer_test.py
index 54a62b5..2540008 100644
--- a/yapftests/reformatter_buganizer_test.py
+++ b/yapftests/reformatter_buganizer_test.py
@@ -511,7 +511,7 @@
# This does bar.
@arg.String('some_path_to_a_file', required=True)
def f():
- print 1
+ print(1)
"""
llines = yapf_test_helper.ParseAndUnwrap(code)
self.assertCodeEqual(code, reformatter.Reformat(llines))