diff --git a/tests/check_new_syntax.py b/tests/check_new_syntax.py index aa9c8f73f..f6945a003 100755 --- a/tests/check_new_syntax.py +++ b/tests/check_new_syntax.py @@ -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