X-Git-Url: https://git.madduck.net/etc/vim.git/blobdiff_plain/b73b77a9b039d5afa6ab32202bff2b2232258d45..eb32729ab562c010d9f644a3bbb2305196b2deb7:/src/black/parsing.py

diff --git a/src/black/parsing.py b/src/black/parsing.py
index c37c12b..70ed99c 100644
--- a/src/black/parsing.py
+++ b/src/black/parsing.py
@@ -11,7 +11,7 @@ if sys.version_info < (3, 8):
 else:
     from typing import Final
 
-from black.mode import Feature, TargetVersion, supports_feature
+from black.mode import VERSION_TO_FEATURES, Feature, TargetVersion, supports_feature
 from black.nodes import syms
 from blib2to3 import pygram
 from blib2to3.pgen2 import driver
@@ -29,11 +29,9 @@ try:
 except ImportError:
     if sys.version_info < (3, 8) and not _IS_PYPY:
         print(
-            (
-                "The typed_ast package is required but not installed.\n"
-                "You can upgrade to Python 3.8+ or install typed_ast with\n"
-                "`python3 -m pip install typed-ast`."
-            ),
+            "The typed_ast package is required but not installed.\n"
+            "You can upgrade to Python 3.8+ or install typed_ast with\n"
+            "`python3 -m pip install typed-ast`.",
             file=sys.stderr,
         )
         sys.exit(1)
@@ -52,7 +50,7 @@ def get_grammars(target_versions: Set[TargetVersion]) -> List[Grammar]:
     if not target_versions:
         # No target_version specified, so try all grammars.
         return [
-            # Python 3.7+
+            # Python 3.7-3.9
             pygram.python_grammar_no_print_statement_no_exec_statement_async_keywords,
             # Python 3.0-3.6
             pygram.python_grammar_no_print_statement_no_exec_statement,
@@ -72,7 +70,7 @@ def get_grammars(target_versions: Set[TargetVersion]) -> List[Grammar]:
     if not supports_feature(target_versions, Feature.ASYNC_KEYWORDS):
         # Python 3.0-3.6
         grammars.append(pygram.python_grammar_no_print_statement_no_exec_statement)
-    if supports_feature(target_versions, Feature.PATTERN_MATCHING):
+    if any(Feature.PATTERN_MATCHING in VERSION_TO_FEATURES[v] for v in target_versions):
         # Python 3.10+
         grammars.append(pygram.python_grammar_soft_keywords)
 
@@ -148,24 +146,29 @@ def lib2to3_unparse(node: Node) -> str:
 
 
 def parse_single_version(
-    src: str, version: Tuple[int, int]
+    src: str, version: Tuple[int, int], *, type_comments: bool
 ) -> Union[ast.AST, ast3.AST]:
     filename = "<unknown>"
     # typed-ast is needed because of feature version limitations in the builtin ast 3.8>
     if sys.version_info >= (3, 8) and version >= (3,):
-        return ast.parse(src, filename, feature_version=version, type_comments=True)
+        return ast.parse(
+            src, filename, feature_version=version, type_comments=type_comments
+        )
 
     if _IS_PYPY:
         # PyPy 3.7 doesn't support type comment tracking which is not ideal, but there's
         # not much we can do as typed-ast won't work either.
         if sys.version_info >= (3, 8):
-            return ast3.parse(src, filename, type_comments=True)
+            return ast3.parse(src, filename, type_comments=type_comments)
         else:
             return ast3.parse(src, filename)
     else:
-        # Typed-ast is guaranteed to be used here and automatically tracks type
-        # comments separately.
-        return ast3.parse(src, filename, feature_version=version[1])
+        if type_comments:
+            # Typed-ast is guaranteed to be used here and automatically tracks type
+            # comments separately.
+            return ast3.parse(src, filename, feature_version=version[1])
+        else:
+            return ast.parse(src, filename)
 
 
 def parse_ast(src: str) -> Union[ast.AST, ast3.AST]:
@@ -175,11 +178,18 @@ def parse_ast(src: str) -> Union[ast.AST, ast3.AST]:
     first_error = ""
     for version in sorted(versions, reverse=True):
         try:
-            return parse_single_version(src, version)
+            return parse_single_version(src, version, type_comments=True)
         except SyntaxError as e:
             if not first_error:
                 first_error = str(e)
 
+    # Try to parse without type comments
+    for version in sorted(versions, reverse=True):
+        try:
+            return parse_single_version(src, version, type_comments=False)
+        except SyntaxError:
+            pass
+
     raise SyntaxError(first_error)