Remove many checks from check_new_syntax.py (#7023)

These are now checked by the flake8-pyi plugin, which is better tested and more comprehensive. Removing these checks from `check_new_syntax.py` will reduce the risk of a contributor getting two nearly identical error messages for the same line in a PR.
This commit is contained in:
Alex Waygood
2022-01-24 15:30:27 +00:00
committed by GitHub
parent 6346464aed
commit a9ae6b246c

View File

@@ -9,46 +9,11 @@ STUBS_SUPPORTING_PYTHON_2 = frozenset(
path.parent for path in Path("stubs").rglob("METADATA.toml") if "python2 = true" in path.read_text().splitlines()
)
CONTEXT_MANAGER_ALIASES = {"ContextManager": "AbstractContextManager", "AsyncContextManager": "AbstractAsyncContextManager"}
CONTEXTLIB_ALIAS_ALLOWLIST = frozenset({Path("stdlib/contextlib.pyi")})
FORBIDDEN_BUILTIN_TYPING_IMPORTS = frozenset({"List", "FrozenSet", "Set", "Dict", "Tuple", "Type"})
IMPORTED_FROM_TYPING_NOT_TYPING_EXTENSIONS = frozenset(
{"ClassVar", "NewType", "overload", "Text", "Protocol", "runtime_checkable", "NoReturn"}
)
IMPORTED_FROM_COLLECTIONS_ABC_NOT_TYPING_EXTENSIONS = frozenset(
{"Awaitable", "Coroutine", "AsyncIterable", "AsyncIterator", "AsyncGenerator"}
)
# The values in the mapping are what these are called in `collections`
IMPORTED_FROM_COLLECTIONS_NOT_TYPING = {
"Counter": "Counter",
"Deque": "deque",
"DefaultDict": "defaultdict",
"OrderedDict": "OrderedDict",
"ChainMap": "ChainMap",
}
def check_new_syntax(tree: ast.AST, path: Path) -> list[str]:
errors = []
python_2_support_required = any(directory in path.parents for directory in STUBS_SUPPORTING_PYTHON_2)
def check_object_from_typing(node: ast.ImportFrom | ast.Attribute, object_name: str):
if object_name in FORBIDDEN_BUILTIN_TYPING_IMPORTS:
errors.append(f"{path}:{node.lineno}: Use `builtins.{object_name.lower()}` instead of `typing.{object_name}`")
elif object_name in IMPORTED_FROM_COLLECTIONS_NOT_TYPING:
errors.append(
f"{path}:{node.lineno}: "
f"Use `collections.{IMPORTED_FROM_COLLECTIONS_NOT_TYPING[object_name]}` instead of `typing.{object_name}`"
)
elif not python_2_support_required and path not in CONTEXTLIB_ALIAS_ALLOWLIST and object_name in CONTEXT_MANAGER_ALIASES:
errors.append(
f"{path}:{node.lineno}: Use `contextlib.{CONTEXT_MANAGER_ALIASES[object_name]}` instead of `typing.{object_name}`"
)
# We can't yet check for collections.abc imports due to pytype errors
class UnionFinder(ast.NodeVisitor):
def visit_Subscript(self, node: ast.Subscript) -> None:
if isinstance(node.value, ast.Name):
@@ -62,60 +27,6 @@ def check_new_syntax(tree: ast.AST, path: Path) -> list[str]:
self.generic_visit(node)
class OldSyntaxFinder(ast.NodeVisitor):
def visit_ImportFrom(self, node: ast.ImportFrom) -> None:
if node.module == "collections.abc":
imported_classes = node.names
if any(cls.name == "Set" and cls.asname != "AbstractSet" for cls in imported_classes):
errors.append(
f"{path}:{node.lineno}: "
f"Use `from collections.abc import Set as AbstractSet` to avoid confusion with `builtins.set`"
)
elif node.module == "typing_extensions":
for imported_object in node.names:
imported_object_name = imported_object.name
if imported_object_name in FORBIDDEN_BUILTIN_TYPING_IMPORTS:
errors.append(
f"{path}:{node.lineno}: "
f"Use `builtins.{imported_object_name.lower()}` instead of `typing_extensions.{imported_object_name}`"
)
elif imported_object_name in IMPORTED_FROM_TYPING_NOT_TYPING_EXTENSIONS:
errors.append(
f"{path}:{node.lineno}: "
f"Use `typing.{imported_object_name}` instead of `typing_extensions.{imported_object_name}`"
)
elif imported_object_name in IMPORTED_FROM_COLLECTIONS_ABC_NOT_TYPING_EXTENSIONS:
errors.append(
f"{path}:{node.lineno}: "
f"Use `collections.abc.{imported_object_name}` or `typing.{imported_object_name}` "
f"instead of `typing_extensions.{imported_object_name}`"
)
elif imported_object_name in IMPORTED_FROM_COLLECTIONS_NOT_TYPING:
errors.append(
f"{path}:{node.lineno}: "
f"Use `collections.{IMPORTED_FROM_COLLECTIONS_NOT_TYPING[imported_object_name]}` "
f"instead of `typing_extensions.{imported_object_name}`"
)
elif imported_object_name in CONTEXT_MANAGER_ALIASES:
if python_2_support_required:
errors.append(
f"{path}:{node.lineno}: "
f"Use `typing.{imported_object_name}` instead of `typing_extensions.{imported_object_name}`"
)
else:
errors.append(
f"{path}:{node.lineno}: Use `contextlib.{CONTEXT_MANAGER_ALIASES[imported_object_name]}` "
f"instead of `typing_extensions.{imported_object_name}`"
)
elif node.module == "typing":
for imported_object in node.names:
check_object_from_typing(node, imported_object.name)
def visit_Attribute(self, node: ast.Attribute) -> None:
if isinstance(node.value, ast.Name) and node.value.id == "typing":
check_object_from_typing(node, node.attr)
self.generic_visit(node)
def visit_AnnAssign(self, node: ast.AnnAssign) -> None:
UnionFinder().visit(node.annotation)
@@ -157,12 +68,10 @@ def check_new_syntax(tree: ast.AST, path: Path) -> list[str]:
)
self.generic_visit(node)
if path != Path("stdlib/typing_extensions.pyi"):
OldSyntaxFinder().visit(tree)
if not python_2_support_required:
ObjectClassdefFinder().visit(tree)
OldSyntaxFinder().visit(tree)
IfFinder().visit(tree)
return errors