Repository: google/yapf
Pull request #1090 (2023-05-02 21:09:08)

Resolve py2 grammar (alternative to #776)
Alternative to #776

CC @bwendling 


Patch:
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 @@ def LastLeafNode(node):
 # 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 @@ def ParseCodeToTree(code):
     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)
 
 


Test patch:
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 @@ class ParseCodeToTreeTest(unittest.TestCase):
     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 @@ INITIAL_SYMTAB = dict(
 # 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))