Flake8 Type Annotation Checks
Project description
flake8-annotations
flake8-annotations
is a plugin for Flake8 that detects the absence of PEP 3107-style function annotations and PEP 484-style type comments (see: Caveats).
What this won't do: Check variable annotations (see: PEP 526), respect stub files, or replace mypy.
Installation
Install from PyPi with your favorite pip
invocation:
$ pip install flake8-annotations
It will then be run automatically as part of flake8.
You can verify it's being picked up by invoking the following in your shell:
$ flake8 --version
5.0.2 (flake8-annotations: 2.9.1, mccabe: 0.7.0, pycodestyle: 2.9.0, pyflakes:2.5.0) CPython 3.10.5 on Darwin
Table of Warnings
With the exception of ANN4xx
-level warnings, all warnings are enabled by default.
Function Annotations
ID | Description |
---|---|
ANN001 |
Missing type annotation for function argument |
ANN002 |
Missing type annotation for *args |
ANN003 |
Missing type annotation for **kwargs |
Method Annotations
ID | Description |
---|---|
ANN101 |
Missing type annotation for self in method1 |
ANN102 |
Missing type annotation for cls in classmethod1 |
Return Annotations
ID | Description |
---|---|
ANN201 |
Missing return type annotation for public function |
ANN202 |
Missing return type annotation for protected function |
ANN203 |
Missing return type annotation for secret function |
ANN204 |
Missing return type annotation for special method |
ANN205 |
Missing return type annotation for staticmethod |
ANN206 |
Missing return type annotation for classmethod |
Type Comments
Deprecation notice: Support for type comments will be removed in 3.0
. See this issue for more information.
ID | Description |
---|---|
ANN301 |
PEP 484 disallows both type annotations and type comments |
Opinionated Warnings
These warnings are disabled by default.
ID | Description |
---|---|
ANN401 |
Dynamically typed expressions (typing.Any) are disallowed.2 |
Notes:
- See: PEP 484 and PEP 563 for suggestions on annotating
self
andcls
arguments. - See: Dynamic Typing Caveats
Configuration Options
Some opinionated flags are provided to tailor the linting errors emitted.
--suppress-none-returning
: bool
Suppress ANN200
-level errors for functions that meet one of the following criteria:
- Contain no
return
statement, or - Explicit
return
statement(s) all returnNone
(explicitly or implicitly).
Default: False
--suppress-dummy-args
: bool
Suppress ANN000
-level errors for dummy arguments, defined as _
.
Default: False
--allow-untyped-defs
: bool
Suppress all errors for dynamically typed functions. A function is considered dynamically typed if it does not contain any type hints.
Default: False
--allow-untyped-nested
: bool
Suppress all errors for dynamically typed nested functions. A function is considered dynamically typed if it does not contain any type hints.
Default: False
--mypy-init-return
: bool
Allow omission of a return type hint for __init__
if at least one argument is annotated. See mypy's documentation for additional details.
Default: False
--dispatch-decorators
: list[str]
Comma-separated list of decorators flake8-annotations should consider as dispatch decorators. Linting errors are suppressed for functions decorated with at least one of these functions.
Decorators are matched based on their attribute name. For example, "singledispatch"
will match any of the following:
import functools; @functools.singledispatch
import functools as <alias>; @<alias>.singledispatch
from functools import singledispatch; @singledispatch
NOTE: Deeper imports, such as a.b.singledispatch
are not supported.
See: Generic Functions for additional information.
Default: "singledispatch, singledispatchmethod"
--overload-decorators
: list[str]
Comma-separated list of decorators flake8-annotations should consider as typing.overload
decorators.
Decorators are matched based on their attribute name. For example, "overload"
will match any of the following:
import typing; @typing.overload
import typing as <alias>; @<alias>.overload
from typing import overload; @overload
NOTE: Deeper imports, such as a.b.overload
are not supported.
See: The typing.overload
Decorator for additional information.
Default: "overload"
--allow-star-arg-any
Suppress ANN401
for dynamically typed *args
and **kwargs
.
Default: False
Generic Functions
Per the Python Glossary, a generic function is defined as:
A function composed of multiple functions implementing the same operation for different types. Which implementation should be used during a call is determined by the dispatch algorithm.
In the standard library we have some examples of decorators for implementing these generic functions: functools.singledispatch
and functools.singledispatchmethod
. In the spirit of the purpose of these decorators, errors for missing annotations for functions decorated with at least one of these are ignored.
For example, this code:
import functools
@functools.singledispatch
def foo(a):
print(a)
@foo.register
def _(a: list) -> None:
for idx, thing in enumerate(a):
print(idx, thing)
Will not raise any linting errors for foo
.
Decorator(s) to treat as defining generic functions may be specified by the --dispatch-decorators
configuration option.
The typing.overload
Decorator
Per the typing
documentation:
The
@overload
decorator allows describing functions and methods that support multiple different combinations of argument types. A series of@overload
-decorated definitions must be followed by exactly one non-@overload
-decorated definition (for the same function/method).
In the spirit of the purpose of this decorator, errors for missing annotations for non-@overload
-decorated functions are ignored if they meet this criteria.
For example, this code:
import typing
@typing.overload
def foo(a: int) -> int:
...
def foo(a):
...
Will not raise linting errors for missing annotations for the arguments & return of the non-decorated foo
definition.
Decorator(s) to treat as typing.overload
may be specified by the --overload-decorators
configuration option.
Caveats for PEP 484-style Type Comments
Deprecation notice: Support for type comments will be removed in 3.0
. See this issue for more information.
Mixing argument-level and function-level type comments
Support is provided for mixing argument-level and function-level type comments.
def foo(
arg1, # type: bool
arg2, # type: bool
): # type: (...) -> bool
pass
Note: If present, function-level type comments will override any argument-level type comments.
Partial type comments
Partially type hinted functions are supported for non-static class methods.
For example:
class Foo:
def __init__(self):
# type: () -> None
...
def bar(self, a):
# type: (int) -> int
...
Will consider bar
's self
argument as unannotated and use the int
type hint for a
.
Partial type comments utilizing ellipses as placeholders is also supported:
def foo(arg1, arg2):
# type: (bool) -> bool
pass
Will show arg2
as missing a type hint.
def foo(arg1, arg2):
# type: (..., bool) -> bool
pass
Will show arg1
as missing a type hint.
Dynamic Typing Caveats
Support is only provided for the following patterns:
from typing import any; foo: Any
import typing; foo: typing.Any
import typing as <alias>; foo: <alias>.Any
Nested dynamic types (e.g. typing.Tuple[typing.Any]
) and redefinition (e.g. from typing import Any as Foo
) will not be identified.
Contributing
Development Environment
This project uses Poetry to manage dependencies. With your fork cloned to your local machine, you can install the project and its dependencies to create a development environment using:
$ poetry install
Note: An editable installation of flake8-annotations
in the developer environment is required in order for the plugin to be registered for Flake8. By default, Poetry includes an editable install of the project itself when poetry install
is invoked.
A pre-commit configuration is also provided to create a pre-commit hook so linting errors aren't committed:
$ pre-commit install
Testing & Coverage
A pytest suite is provided, with coverage reporting from pytest-cov. A tox configuration is provided to test across all supported versions of Python. Testing will be skipped for Python versions that cannot be found.
$ tox
Details on missing coverage, including in the test suite, is provided in the report to allow the user to generate additional tests for full coverage.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file flake8-annotations-2.9.1.tar.gz
.
File metadata
- Download URL: flake8-annotations-2.9.1.tar.gz
- Upload date:
- Size: 23.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.1 CPython/3.9.13
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 11f09efb99ae63c8f9d6b492b75fe147fbc323179fddfe00b2e56eefeca42f57 |
|
MD5 | b515cb0cd5142b05f52f1d11add89f52 |
|
BLAKE2b-256 | 5fd4ed8d8e72c784dcb61df1dab7cbce61fcb3b6cd1191f60e006053e6f52925 |
File details
Details for the file flake8_annotations-2.9.1-py3-none-any.whl
.
File metadata
- Download URL: flake8_annotations-2.9.1-py3-none-any.whl
- Upload date:
- Size: 18.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.1 CPython/3.9.13
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | a4385158a7a9fc8af1d8820a2f4c8d03387997006a83f5f8bfe5bc6085bdf88a |
|
MD5 | fbd073f70fccacf9a0642a087ef2172b |
|
BLAKE2b-256 | f6dcee0cfd300f22f169d42fd951c4a44840041f777987de8c56f861be5faefd |