diff --git a/CHANGELOG.md b/CHANGELOG.md index af85cc27..499a3f0f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,8 @@ Features: * Support Python 3.11. * Support `typing_extensions.overload` and `typing_extensions.NamedTuple`. (The latter is not yet released, but will be in the next version of `typing_extensions`.) +* Introduce Y044: Discourage unnecessary `from __future__ import annotations` import. + Contributed by Torsten Wörtwein. ## 22.5.1 diff --git a/README.md b/README.md index 94eadbed..6f6bb786 100644 --- a/README.md +++ b/README.md @@ -74,6 +74,7 @@ currently emitted: | Y040 | Never explicitly inherit from `object`, as all classes implicitly inherit from `object` in Python 3. This error code is incompatible with stubs supporting Python 2. | Y041 | Y041 detects redundant numeric unions. For example, PEP 484 specifies that type checkers should treat `int` as an implicit subtype of `float`, so `int` is redundant in the union `int \| float`. In the same way, `int` is redundant in the union `int \| complex`, and `float` is redundant in the union `float \| complex`. | Y043 | Do not use names ending in "T" for private type aliases. (The "T" suffix implies that an object is a `TypeVar`.) +| Y044 | `from __future__ import annotations` has no effect in stub files, as forward references in stubs are enabled by default. Many error codes enforce modern conventions, and some cannot yet be used in all cases: diff --git a/pyi.py b/pyi.py index f0f8f114..3d9c54e9 100644 --- a/pyi.py +++ b/pyi.py @@ -740,6 +740,10 @@ def visit_ImportFrom(self, node: ast.ImportFrom) -> None: for obj in imported_objects ): return self.error(node, Y025) + elif module_name == "__future__" and any( + obj.name == "annotations" for obj in imported_objects + ): + return self.error(node, Y044) for obj in imported_objects: self._check_import_or_attribute( @@ -1669,3 +1673,4 @@ def parse_options( Y040 = 'Y040 Do not inherit from "object" explicitly, as it is redundant in Python 3' Y041 = 'Y041 Use "{implicit_supertype}" instead of "{implicit_subtype} | {implicit_supertype}" (see "The numeric tower" in PEP 484)' Y043 = 'Y043 Bad name for a type alias (the "T" suffix implies a TypeVar)' +Y044 = 'Y044 "from __future__ import annotations" has no effect in stub files.' diff --git a/tests/imports.pyi b/tests/imports.pyi index 069cf6b1..1392827d 100644 --- a/tests/imports.pyi +++ b/tests/imports.pyi @@ -3,6 +3,9 @@ # Note: DO NOT RUN ISORT ON THIS FILE. # It's excluded in our pyproject.toml. +# BAD IMPORTS (Y044) +from __future__ import annotations # Y044 "from __future__ import annotations" has no effect in stub files. + # GOOD IMPORTS import typing import typing_extensions