Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update the list of banned imports now that everything is re-exported from typing_extensions #434

Merged
merged 1 commit into from
Oct 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Other changes:
attributes has been removed. Use `flake8 --version` from the command line, or
`importlib.metadata.version("flake8_pyi")` at runtime, to determine the
version of `flake8-pyi` installed at runtime.
* Y022 and Y037 now flag more imports from `typing_extensions`.

## 23.10.0

Expand Down
2 changes: 1 addition & 1 deletion ERRORCODES.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ The following warnings are currently emitted by default:
| Y034 | Y034 detects common errors where certain methods are annotated as having a fixed return type, despite returning `self` at runtime. Such methods should be annotated with `typing_extensions.Self`. This check looks for:<br><br>&nbsp;&nbsp;**1.**&nbsp;&nbsp;Any in-place BinOp dunder methods (`__iadd__`, `__ior__`, etc.) that do not return `Self`.<br>&nbsp;&nbsp;**2.**&nbsp;&nbsp;`__new__`, `__enter__` and `__aenter__` methods that return the class's name unparameterised.<br>&nbsp;&nbsp;**3.**&nbsp;&nbsp;`__iter__` methods that return `Iterator`, even if the class inherits directly from `Iterator`.<br>&nbsp;&nbsp;**4.**&nbsp;&nbsp;`__aiter__` methods that return `AsyncIterator`, even if the class inherits directly from `AsyncIterator`.<br><br>This check excludes methods decorated with `@overload` or `@abstractmethod`.
| Y035 | `__all__`, `__match_args__` and `__slots__` in a stub file should always have values, as these special variables in a `.pyi` file have identical semantics in a stub as at runtime. E.g. write `__all__ = ["foo", "bar"]` instead of `__all__: list[str]`.
| Y036 | Y036 detects common errors in `__exit__` and `__aexit__` methods. For example, the first argument in an `__exit__` method should either be annotated with `object`, `_typeshed.Unused` (a special alias for `object`) or `type[BaseException] \| None`.
| Y037 | Use PEP 604 syntax instead of `typing.Union` and `typing.Optional`. E.g. use `str \| int` instead of `Union[str, int]`, and use `str \| None` instead of `Optional[str]`.
| Y037 | Use PEP 604 syntax instead of `typing(_extensions).Union` and `typing(_extensions).Optional`. E.g. use `str \| int` instead of `Union[str, int]`, and use `str \| None` instead of `Optional[str]`.
| Y038 | Use `from collections.abc import Set as AbstractSet` instead of `from typing import AbstractSet`.
| Y039 | Use `str` instead of `typing.Text`.
| Y040 | Never explicitly inherit from `object`, as all classes implicitly inherit from `object` in Python 3.
Expand Down
148 changes: 62 additions & 86 deletions pyi.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,93 +63,69 @@ class TypeVarInfo(NamedTuple):


_MAPPING_SLICE = "KeyType, ValueType"
_TYPE_SLICE = "MyClass"
_COUNTER_SLICE = "KeyType"
_COROUTINE_SLICE = "YieldType, SendType, ReturnType"
_ASYNCGEN_SLICE = "YieldType, SendType"

# Y022: Use stdlib imports instead of aliases from typing/typing_extensions
_BAD_Y022_IMPORTS: dict[str, tuple[str, str | None]] = {
# typing aliases for collections
"typing.Counter": ("collections.Counter", _COUNTER_SLICE),
"typing.Deque": ("collections.deque", "T"),
"typing.DefaultDict": ("collections.defaultdict", _MAPPING_SLICE),
"typing.ChainMap": ("collections.ChainMap", _MAPPING_SLICE),
"typing.OrderedDict": ("collections.OrderedDict", _MAPPING_SLICE),
# typing aliases for builtins
"typing.Dict": ("dict", _MAPPING_SLICE),
"typing.FrozenSet": ("frozenset", "T"),
"typing.List": ("list", "T"),
"typing.Set": ("set", "T"),
"typing.Tuple": ("tuple", "Foo, Bar"),
"typing.Type": ("type", _TYPE_SLICE),
# typing aliases for contextlib
"typing.ContextManager": ("contextlib.AbstractContextManager", "T"),
"typing.AsyncContextManager": ("contextlib.AbstractAsyncContextManager", "T"),
# typing aliases for re
"typing.Match": ("re.Match", "T"),
"typing.Pattern": ("re.Pattern", "T"),
# typing_extensions aliases for collections
"typing_extensions.Counter": ("collections.Counter", _COUNTER_SLICE),
"typing_extensions.Deque": ("collections.deque", "T"),
"typing_extensions.DefaultDict": ("collections.defaultdict", _MAPPING_SLICE),
"typing_extensions.ChainMap": ("collections.ChainMap", _MAPPING_SLICE),
"typing_extensions.OrderedDict": ("collections.OrderedDict", _MAPPING_SLICE),
# One typing_extensions alias for a builtin
"typing_extensions.Type": ("type", _TYPE_SLICE),
# Typing_extensions aliases for contextlib
"typing_extensions.ContextManager": ("contextlib.AbstractContextManager", "T"),
"typing_extensions.AsyncContextManager": (
"contextlib.AbstractAsyncContextManager",
"T",
),
# typing aliases for collections.abc
# typing.AbstractSet and typing.ByteString are deliberately omitted
# Aliases for collections
"Counter": ("collections.Counter", "KeyType"),
"Deque": ("collections.deque", "T"),
"DefaultDict": ("collections.defaultdict", _MAPPING_SLICE),
"ChainMap": ("collections.ChainMap", _MAPPING_SLICE),
"OrderedDict": ("collections.OrderedDict", _MAPPING_SLICE),
# Aliases for builtins
"Dict": ("dict", _MAPPING_SLICE),
"FrozenSet": ("frozenset", "T"),
"List": ("list", "T"),
"Set": ("set", "T"),
"Tuple": ("tuple", "Foo, Bar"),
"Type": ("type", "MyClass"),
# Aliases for contextlib
"ContextManager": ("contextlib.AbstractContextManager", "T"),
"AsyncContextManager": ("contextlib.AbstractAsyncContextManager", "T"),
# Aliases for re
"Match": ("re.Match", "T"),
"Pattern": ("re.Pattern", "T"),
# Aliases for collections.abc
# AbstractSet and ByteString are deliberately omitted
# (special-cased elsewhere).
# If the second element of the tuple is `None`,
# it signals that the object shouldn't be parameterized
"typing.Collection": ("collections.abc.Collection", "T"),
"typing.ItemsView": ("collections.abc.ItemsView", _MAPPING_SLICE),
"typing.KeysView": ("collections.abc.KeysView", "KeyType"),
"typing.Mapping": ("collections.abc.Mapping", _MAPPING_SLICE),
"typing.MappingView": ("collections.abc.MappingView", None),
"typing.MutableMapping": ("collections.abc.MutableMapping", _MAPPING_SLICE),
"typing.MutableSequence": ("collections.abc.MutableSequence", "T"),
"typing.MutableSet": ("collections.abc.MutableSet", "T"),
"typing.Sequence": ("collections.abc.Sequence", "T"),
"typing.ValuesView": ("collections.abc.ValuesView", "ValueType"),
"typing.Iterable": ("collections.abc.Iterable", "T"),
"typing.Iterator": ("collections.abc.Iterator", "T"),
"typing.Generator": (
"collections.abc.Generator",
"YieldType, SendType, ReturnType",
),
"typing.Hashable": ("collections.abc.Hashable", None),
"typing.Reversible": ("collections.abc.Reversible", "T"),
"typing.Sized": ("collections.abc.Sized", None),
"typing.Coroutine": ("collections.abc.Coroutine", _COROUTINE_SLICE),
"typing.AsyncGenerator": ("collections.abc.AsyncGenerator", _ASYNCGEN_SLICE),
"typing.AsyncIterator": ("collections.abc.AsyncIterator", "T"),
"typing.AsyncIterable": ("collections.abc.AsyncIterable", "T"),
"typing.Awaitable": ("collections.abc.Awaitable", "T"),
"typing.Callable": ("collections.abc.Callable", None),
"typing.Container": ("collections.abc.Container", "T"),
# typing_extensions aliases for collections.abc
"typing_extensions.Awaitable": ("collections.abc.Awaitable", "T"),
"typing_extensions.Coroutine": ("collections.abc.Coroutine", _COROUTINE_SLICE),
"typing_extensions.AsyncIterable": ("collections.abc.AsyncIterable", "T"),
"typing_extensions.AsyncIterator": ("collections.abc.AsyncIterator", "T"),
"typing_extensions.AsyncGenerator": (
"collections.abc.AsyncGenerator",
_ASYNCGEN_SLICE,
),
"Collection": ("collections.abc.Collection", "T"),
"ItemsView": ("collections.abc.ItemsView", _MAPPING_SLICE),
"KeysView": ("collections.abc.KeysView", "KeyType"),
"Mapping": ("collections.abc.Mapping", _MAPPING_SLICE),
"MappingView": ("collections.abc.MappingView", None),
"MutableMapping": ("collections.abc.MutableMapping", _MAPPING_SLICE),
"MutableSequence": ("collections.abc.MutableSequence", "T"),
"MutableSet": ("collections.abc.MutableSet", "T"),
"Sequence": ("collections.abc.Sequence", "T"),
"ValuesView": ("collections.abc.ValuesView", "ValueType"),
"Iterable": ("collections.abc.Iterable", "T"),
"Iterator": ("collections.abc.Iterator", "T"),
"Generator": ("collections.abc.Generator", "YieldType, SendType, ReturnType"),
"Hashable": ("collections.abc.Hashable", None),
"Reversible": ("collections.abc.Reversible", "T"),
"Sized": ("collections.abc.Sized", None),
"Coroutine": ("collections.abc.Coroutine", "YieldType, SendType, ReturnType"),
"AsyncGenerator": ("collections.abc.AsyncGenerator", "YieldType, SendType"),
"AsyncIterator": ("collections.abc.AsyncIterator", "T"),
"AsyncIterable": ("collections.abc.AsyncIterable", "T"),
"Awaitable": ("collections.abc.Awaitable", "T"),
"Callable": ("collections.abc.Callable", None),
"Container": ("collections.abc.Container", "T"),
}

# Y023: Import things from typing instead of typing_extensions
# if they're available from the typing module on 3.7+
_BAD_TYPINGEXTENSIONS_Y023_IMPORTS = frozenset(
{
"AnyStr",
"BinaryIO",
"ForwardRef",
"Generic",
"IO",
"Protocol",
"TextIO",
"runtime_checkable",
"NewType",
"overload",
Expand Down Expand Up @@ -922,14 +898,24 @@ def _check_import_or_attribute(
error_message = Y057.format(module=module_name)

# Y022 errors
elif fullname in _BAD_Y022_IMPORTS:
good_cls_name, slice_contents = _BAD_Y022_IMPORTS[fullname]
elif module_name in _TYPING_MODULES and object_name in _BAD_Y022_IMPORTS:
good_cls_name, slice_contents = _BAD_Y022_IMPORTS[object_name]
params = "" if slice_contents is None else f"[{slice_contents}]"
error_message = Y022.format(
good_syntax=f'"{good_cls_name}{params}"',
bad_syntax=f'"{fullname}{params}"',
)

# Y037 errors
elif module_name in _TYPING_MODULES and object_name == "Optional":
error_message = Y037.format(
old_syntax=fullname, example='"int | None" instead of "Optional[int]"'
)
elif module_name in _TYPING_MODULES and object_name == "Union":
error_message = Y037.format(
old_syntax=fullname, example='"int | str" instead of "Union[int, str]"'
)

# Y023 errors
elif module_name == "typing_extensions":
if object_name in _BAD_TYPINGEXTENSIONS_Y023_IMPORTS:
Expand All @@ -949,16 +935,6 @@ def _check_import_or_attribute(
elif fullname == "collections.namedtuple":
error_message = Y024

# Y037 errors
elif fullname == "typing.Optional":
error_message = Y037.format(
old_syntax=fullname, example='"int | None" instead of "Optional[int]"'
)
elif fullname == "typing.Union":
error_message = Y037.format(
old_syntax=fullname, example='"int | str" instead of "Union[int, str]"'
)

# Y039 errors
elif fullname == "typing.Text":
error_message = Y039
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ local_scheme = "no-local-version"
[tool.isort]
profile = "black"
combine_as_imports = true
skip = ["tests/imports.pyi"]
skip = ["tests/imports.pyi", "tests/pep604_union_types.pyi"]
skip_gitignore = true

[tool.black]
Expand Down
40 changes: 31 additions & 9 deletions tests/imports.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -80,17 +80,8 @@ from typing import Dict # Y022 Use "dict[KeyType, ValueType]" instead of "typin
from typing import Counter # Y022 Use "collections.Counter[KeyType]" instead of "typing.Counter[KeyType]" (PEP 585 syntax)
from typing import AsyncContextManager # Y022 Use "contextlib.AbstractAsyncContextManager[T]" instead of "typing.AsyncContextManager[T]" (PEP 585 syntax)
from typing import ChainMap # Y022 Use "collections.ChainMap[KeyType, ValueType]" instead of "typing.ChainMap[KeyType, ValueType]" (PEP 585 syntax)
from typing_extensions import Type # Y022 Use "type[MyClass]" instead of "typing_extensions.Type[MyClass]" (PEP 585 syntax)
from typing_extensions import DefaultDict # Y022 Use "collections.defaultdict[KeyType, ValueType]" instead of "typing_extensions.DefaultDict[KeyType, ValueType]" (PEP 585 syntax)
from typing_extensions import ChainMap # Y022 Use "collections.ChainMap[KeyType, ValueType]" instead of "typing_extensions.ChainMap[KeyType, ValueType]" (PEP 585 syntax)
from typing_extensions import AsyncContextManager # Y022 Use "contextlib.AbstractAsyncContextManager[T]" instead of "typing_extensions.AsyncContextManager[T]" (PEP 585 syntax)
from typing_extensions import Awaitable # Y022 Use "collections.abc.Awaitable[T]" instead of "typing_extensions.Awaitable[T]" (PEP 585 syntax)
from typing_extensions import ContextManager # Y022 Use "contextlib.AbstractContextManager[T]" instead of "typing_extensions.ContextManager[T]" (PEP 585 syntax)
from typing_extensions import AsyncGenerator # Y022 Use "collections.abc.AsyncGenerator[YieldType, SendType]" instead of "typing_extensions.AsyncGenerator[YieldType, SendType]" (PEP 585 syntax)
from typing_extensions import Coroutine # Y022 Use "collections.abc.Coroutine[YieldType, SendType, ReturnType]" instead of "typing_extensions.Coroutine[YieldType, SendType, ReturnType]" (PEP 585 syntax)
from typing import ContextManager # Y022 Use "contextlib.AbstractContextManager[T]" instead of "typing.ContextManager[T]" (PEP 585 syntax)
from typing import OrderedDict # Y022 Use "collections.OrderedDict[KeyType, ValueType]" instead of "typing.OrderedDict[KeyType, ValueType]" (PEP 585 syntax)
from typing_extensions import OrderedDict # Y022 Use "collections.OrderedDict[KeyType, ValueType]" instead of "typing_extensions.OrderedDict[KeyType, ValueType]" (PEP 585 syntax)
from typing import Callable # Y022 Use "collections.abc.Callable" instead of "typing.Callable" (PEP 585 syntax)
from typing import Container # Y022 Use "collections.abc.Container[T]" instead of "typing.Container[T]" (PEP 585 syntax)
from typing import Hashable # Y022 Use "collections.abc.Hashable" instead of "typing.Hashable" (PEP 585 syntax)
Expand All @@ -116,6 +107,37 @@ from typing import Reversible # Y022 Use "collections.abc.Reversible[T]" instea
from typing import Generator # Y022 Use "collections.abc.Generator[YieldType, SendType, ReturnType]" instead of "typing.Generator[YieldType, SendType, ReturnType]" (PEP 585 syntax)
from typing import Match # Y022 Use "re.Match[T]" instead of "typing.Match[T]" (PEP 585 syntax)
from typing import Pattern # Y022 Use "re.Pattern[T]" instead of "typing.Pattern[T]" (PEP 585 syntax)
from typing_extensions import Dict # Y022 Use "dict[KeyType, ValueType]" instead of "typing_extensions.Dict[KeyType, ValueType]" (PEP 585 syntax)
from typing_extensions import Counter # Y022 Use "collections.Counter[KeyType]" instead of "typing_extensions.Counter[KeyType]" (PEP 585 syntax)
from typing_extensions import AsyncContextManager # Y022 Use "contextlib.AbstractAsyncContextManager[T]" instead of "typing_extensions.AsyncContextManager[T]" (PEP 585 syntax)
from typing_extensions import ChainMap # Y022 Use "collections.ChainMap[KeyType, ValueType]" instead of "typing_extensions.ChainMap[KeyType, ValueType]" (PEP 585 syntax)
from typing_extensions import ContextManager # Y022 Use "contextlib.AbstractContextManager[T]" instead of "typing_extensions.ContextManager[T]" (PEP 585 syntax)
from typing_extensions import OrderedDict # Y022 Use "collections.OrderedDict[KeyType, ValueType]" instead of "typing_extensions.OrderedDict[KeyType, ValueType]" (PEP 585 syntax)
from typing_extensions import Callable # Y022 Use "collections.abc.Callable" instead of "typing_extensions.Callable" (PEP 585 syntax)
from typing_extensions import Container # Y022 Use "collections.abc.Container[T]" instead of "typing_extensions.Container[T]" (PEP 585 syntax)
from typing_extensions import Hashable # Y022 Use "collections.abc.Hashable" instead of "typing_extensions.Hashable" (PEP 585 syntax)
from typing_extensions import ItemsView # Y022 Use "collections.abc.ItemsView[KeyType, ValueType]" instead of "typing_extensions.ItemsView[KeyType, ValueType]" (PEP 585 syntax)
from typing_extensions import Iterable # Y022 Use "collections.abc.Iterable[T]" instead of "typing_extensions.Iterable[T]" (PEP 585 syntax)
from typing_extensions import Iterator # Y022 Use "collections.abc.Iterator[T]" instead of "typing_extensions.Iterator[T]" (PEP 585 syntax)
from typing_extensions import KeysView # Y022 Use "collections.abc.KeysView[KeyType]" instead of "typing_extensions.KeysView[KeyType]" (PEP 585 syntax)
from typing_extensions import Mapping # Y022 Use "collections.abc.Mapping[KeyType, ValueType]" instead of "typing_extensions.Mapping[KeyType, ValueType]" (PEP 585 syntax)
from typing_extensions import MappingView # Y022 Use "collections.abc.MappingView" instead of "typing_extensions.MappingView" (PEP 585 syntax)
from typing_extensions import MutableMapping # Y022 Use "collections.abc.MutableMapping[KeyType, ValueType]" instead of "typing_extensions.MutableMapping[KeyType, ValueType]" (PEP 585 syntax)
from typing_extensions import MutableSequence # Y022 Use "collections.abc.MutableSequence[T]" instead of "typing_extensions.MutableSequence[T]" (PEP 585 syntax)
from typing_extensions import MutableSet # Y022 Use "collections.abc.MutableSet[T]" instead of "typing_extensions.MutableSet[T]" (PEP 585 syntax)
from typing_extensions import Sequence # Y022 Use "collections.abc.Sequence[T]" instead of "typing_extensions.Sequence[T]" (PEP 585 syntax)
from typing_extensions import Sized # Y022 Use "collections.abc.Sized" instead of "typing_extensions.Sized" (PEP 585 syntax)
from typing_extensions import ValuesView # Y022 Use "collections.abc.ValuesView[ValueType]" instead of "typing_extensions.ValuesView[ValueType]" (PEP 585 syntax)
from typing_extensions import Awaitable # Y022 Use "collections.abc.Awaitable[T]" instead of "typing_extensions.Awaitable[T]" (PEP 585 syntax)
from typing_extensions import AsyncIterator # Y022 Use "collections.abc.AsyncIterator[T]" instead of "typing_extensions.AsyncIterator[T]" (PEP 585 syntax)
from typing_extensions import AsyncIterable # Y022 Use "collections.abc.AsyncIterable[T]" instead of "typing_extensions.AsyncIterable[T]" (PEP 585 syntax)
from typing_extensions import Coroutine # Y022 Use "collections.abc.Coroutine[YieldType, SendType, ReturnType]" instead of "typing_extensions.Coroutine[YieldType, SendType, ReturnType]" (PEP 585 syntax)
from typing_extensions import Collection # Y022 Use "collections.abc.Collection[T]" instead of "typing_extensions.Collection[T]" (PEP 585 syntax)
from typing_extensions import AsyncGenerator # Y022 Use "collections.abc.AsyncGenerator[YieldType, SendType]" instead of "typing_extensions.AsyncGenerator[YieldType, SendType]" (PEP 585 syntax)
from typing_extensions import Reversible # Y022 Use "collections.abc.Reversible[T]" instead of "typing_extensions.Reversible[T]" (PEP 585 syntax)
from typing_extensions import Generator # Y022 Use "collections.abc.Generator[YieldType, SendType, ReturnType]" instead of "typing_extensions.Generator[YieldType, SendType, ReturnType]" (PEP 585 syntax)
from typing_extensions import Match # Y022 Use "re.Match[T]" instead of "typing_extensions.Match[T]" (PEP 585 syntax)
from typing_extensions import Pattern # Y022 Use "re.Pattern[T]" instead of "typing_extensions.Pattern[T]" (PEP 585 syntax)

# BAD IMPORTS (Y023 code)
from typing_extensions import ClassVar # Y023 Use "typing.ClassVar[T]" instead of "typing_extensions.ClassVar[T]"
Expand Down
Loading