flake8-annotations


Nameflake8-annotations JSON
Version 3.1.0 PyPI version JSON
download
home_pagehttps://github.com/sco1/flake8-annotations
SummaryFlake8 Type Annotation Checks
upload_time2024-05-06 18:48:02
maintainerNone
docs_urlNone
authorS Co1
requires_python>=3.8.1
licenseMIT
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # flake8-annotations
[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/flake8-annotations/3.1.0?logo=python&logoColor=FFD43B)](https://pypi.org/project/flake8-annotations/)
[![PyPI](https://img.shields.io/pypi/v/flake8-annotations?logo=Python&logoColor=FFD43B)](https://pypi.org/project/flake8-annotations/)
[![PyPI - License](https://img.shields.io/pypi/l/flake8-annotations?color=magenta)](https://github.com/sco1/flake8-annotations/blob/main/LICENSE)
[![pre-commit.ci status](https://results.pre-commit.ci/badge/github/sco1/flake8-annotations/main.svg)](https://results.pre-commit.ci/latest/github/sco1/flake8-annotations/main)
[![Open in Visual Studio Code](https://img.shields.io/badge/Open%20in-VSCode.dev-blue)](https://github.dev/sco1/flake8-annotations)

`flake8-annotations` is a plugin for [Flake8](http://flake8.pycqa.org/en/latest/) that detects the absence of [PEP 3107-style](https://www.python.org/dev/peps/pep-3107/) function annotations.

What this won't do: replace [mypy](http://mypy-lang.org/), check type comments (see: [PEP 484](https://peps.python.org/pep-0484/#type-comments)), check variable annotations (see: [PEP 526](https://www.python.org/dev/peps/pep-0526/)), or respect stub files.

## Installation
Install from PyPi with your favorite `pip` invocation:

```bash
$ 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:


<!-- [[[cog
import cog
from subprocess import PIPE, run
out = run(["flake8", "--version"], stdout=PIPE, encoding="ascii")
ver_str = out.stdout.replace("\n", "")
cog.out(
    f"```bash\n$ flake8 --version\n{ver_str}\n```"
)
]]] -->
```bash
$ flake8 --version
7.0.0 (flake8-annotations: 3.1.0, mccabe: 0.7.0, pycodestyle: 2.11.1, pyflakes: 3.2.0) CPython 3.12.3 on Darwin
```
<!-- [[[end]]] -->

## 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 method<sup>1</sup>     |
| `ANN102` | Missing type annotation for `cls` in classmethod<sup>1</sup> |

### 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        |

### Opinionated Warnings
These warnings are disabled by default.
| ID       | Description                                                             |
|----------|-------------------------------------------------------------------------|
| `ANN401` | Dynamically typed expressions (typing.Any) are disallowed<sup>2,3</sup> |
| `ANN402` | Type comments are disallowed<sup>3</sup>                                |

Use [`extend-select`](https://flake8.pycqa.org/en/latest/user/options.html#cmdoption-flake8-extend-ignore) to enable opinionated warnings without overriding other implicit configurations<sup>4</sup>.

**Notes:**
1. See: [PEP 484](https://www.python.org/dev/peps/pep-0484/#annotating-instance-and-class-methods) and [PEP 563](https://www.python.org/dev/peps/pep-0563/) for suggestions on annotating `self` and `cls` arguments
2. See: [Dynamic Typing Caveats](#dynamic-typing-caveats)
3. Only function declarations are considered by this plugin; type annotations in function/module bodies are not checked 
4. Common pitfall: the use of [`ignore`](https://flake8.pycqa.org/en/latest/user/options.html#cmdoption-flake8-ignore) will enable all implicitly disabled warnings

## 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 return `None` (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](https://mypy.readthedocs.io/en/stable/class_basics.html?#annotating-init-methods) 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](#generic-functions) for additional information.

Default: `"singledispatch, singledispatchmethod"`

### `--overload-decorators`: `list[str]`
Comma-separated list of decorators flake8-annotations should consider as [`typing.overload`](https://docs.python.org/3/library/typing.html#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](#the-typingoverload-decorator) for additional information.

Default: `"overload"`

### `--allow-star-arg-any`
Suppress `ANN401` for dynamically typed `*args` and `**kwargs`.

Default: `False`

### `--respect-type-ignore`
Suppress linting errors for functions annotated with a `# type: ignore` comment.

**NOTE:** Type ignore tags are not considered, e.g. `# type: ignore[arg-type]` is treated the same as `# type: ignore`.

Default: `False`


## Generic Functions
Per the Python Glossary, a [generic function](https://docs.python.org/3/glossary.html#term-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`](https://docs.python.org/3/library/functools.html#functools.singledispatch) and [`functools.singledispatchmethod`](https://docs.python.org/3/library/functools.html#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:

```py
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`](#--dispatch-decorators-liststr) configuration option.

## The `typing.overload` Decorator
Per the [`typing`](https://docs.python.org/3/library/typing.html#typing.overload) 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:

```py
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`](#--overload-decorators-liststr) configuration option.

## 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
### Python Version Support
A best attempt is made to support Python versions until they reach EOL, after which support will be formally dropped by the next minor or major release of this package, whichever arrives first. The status of Python versions can be found [here](https://devguide.python.org/versions/).

### Development Environment
This project uses [Poetry](https://python-poetry.org/) 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:

```bash
$ 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](https://pre-commit.com) configuration is also provided to create a pre-commit hook so linting errors aren't committed:

```bash
$ pre-commit install
```

### Testing & Coverage
A [pytest](https://docs.pytest.org/en/latest/) suite is provided, with coverage reporting from [pytest-cov](https://github.com/pytest-dev/pytest-cov). A [tox](https://github.com/tox-dev/tox/) configuration is provided to test across all supported versions of Python. Testing will be skipped for Python versions that cannot be found.

```bash
$ 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.


            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/sco1/flake8-annotations",
    "name": "flake8-annotations",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.8.1",
    "maintainer_email": null,
    "keywords": null,
    "author": "S Co1",
    "author_email": "sco1.git@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/c2/9e/b7d8b9c75987da2cd57244d90b97887ff3db0778638b4c0ef49ae98b9c0d/flake8_annotations-3.1.0.tar.gz",
    "platform": null,
    "description": "# flake8-annotations\n[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/flake8-annotations/3.1.0?logo=python&logoColor=FFD43B)](https://pypi.org/project/flake8-annotations/)\n[![PyPI](https://img.shields.io/pypi/v/flake8-annotations?logo=Python&logoColor=FFD43B)](https://pypi.org/project/flake8-annotations/)\n[![PyPI - License](https://img.shields.io/pypi/l/flake8-annotations?color=magenta)](https://github.com/sco1/flake8-annotations/blob/main/LICENSE)\n[![pre-commit.ci status](https://results.pre-commit.ci/badge/github/sco1/flake8-annotations/main.svg)](https://results.pre-commit.ci/latest/github/sco1/flake8-annotations/main)\n[![Open in Visual Studio Code](https://img.shields.io/badge/Open%20in-VSCode.dev-blue)](https://github.dev/sco1/flake8-annotations)\n\n`flake8-annotations` is a plugin for [Flake8](http://flake8.pycqa.org/en/latest/) that detects the absence of [PEP 3107-style](https://www.python.org/dev/peps/pep-3107/) function annotations.\n\nWhat this won't do: replace [mypy](http://mypy-lang.org/), check type comments (see: [PEP 484](https://peps.python.org/pep-0484/#type-comments)), check variable annotations (see: [PEP 526](https://www.python.org/dev/peps/pep-0526/)), or respect stub files.\n\n## Installation\nInstall from PyPi with your favorite `pip` invocation:\n\n```bash\n$ pip install flake8-annotations\n```\n\nIt will then be run automatically as part of flake8.\n\nYou can verify it's being picked up by invoking the following in your shell:\n\n\n<!-- [[[cog\nimport cog\nfrom subprocess import PIPE, run\nout = run([\"flake8\", \"--version\"], stdout=PIPE, encoding=\"ascii\")\nver_str = out.stdout.replace(\"\\n\", \"\")\ncog.out(\n    f\"```bash\\n$ flake8 --version\\n{ver_str}\\n```\"\n)\n]]] -->\n```bash\n$ flake8 --version\n7.0.0 (flake8-annotations: 3.1.0, mccabe: 0.7.0, pycodestyle: 2.11.1, pyflakes: 3.2.0) CPython 3.12.3 on Darwin\n```\n<!-- [[[end]]] -->\n\n## Table of Warnings\nWith the exception of `ANN4xx`-level warnings, all warnings are enabled by default.\n\n### Function Annotations\n| ID       | Description                                   |\n|----------|-----------------------------------------------|\n| `ANN001` | Missing type annotation for function argument |\n| `ANN002` | Missing type annotation for `*args`           |\n| `ANN003` | Missing type annotation for `**kwargs`        |\n\n### Method Annotations\n| ID       | Description                                                  |\n|----------|--------------------------------------------------------------|\n| `ANN101` | Missing type annotation for `self` in method<sup>1</sup>     |\n| `ANN102` | Missing type annotation for `cls` in classmethod<sup>1</sup> |\n\n### Return Annotations\n| ID       | Description                                           |\n|----------|-------------------------------------------------------|\n| `ANN201` | Missing return type annotation for public function    |\n| `ANN202` | Missing return type annotation for protected function |\n| `ANN203` | Missing return type annotation for secret function    |\n| `ANN204` | Missing return type annotation for special method     |\n| `ANN205` | Missing return type annotation for staticmethod       |\n| `ANN206` | Missing return type annotation for classmethod        |\n\n### Opinionated Warnings\nThese warnings are disabled by default.\n| ID       | Description                                                             |\n|----------|-------------------------------------------------------------------------|\n| `ANN401` | Dynamically typed expressions (typing.Any) are disallowed<sup>2,3</sup> |\n| `ANN402` | Type comments are disallowed<sup>3</sup>                                |\n\nUse [`extend-select`](https://flake8.pycqa.org/en/latest/user/options.html#cmdoption-flake8-extend-ignore) to enable opinionated warnings without overriding other implicit configurations<sup>4</sup>.\n\n**Notes:**\n1. See: [PEP 484](https://www.python.org/dev/peps/pep-0484/#annotating-instance-and-class-methods) and [PEP 563](https://www.python.org/dev/peps/pep-0563/) for suggestions on annotating `self` and `cls` arguments\n2. See: [Dynamic Typing Caveats](#dynamic-typing-caveats)\n3. Only function declarations are considered by this plugin; type annotations in function/module bodies are not checked \n4. Common pitfall: the use of [`ignore`](https://flake8.pycqa.org/en/latest/user/options.html#cmdoption-flake8-ignore) will enable all implicitly disabled warnings\n\n## Configuration Options\nSome opinionated flags are provided to tailor the linting errors emitted.\n\n### `--suppress-none-returning`: `bool`\nSuppress `ANN200`-level errors for functions that meet one of the following criteria:\n  * Contain no `return` statement, or\n  * Explicit `return` statement(s) all return `None` (explicitly or implicitly).\n\nDefault: `False`\n\n### `--suppress-dummy-args`: `bool`\nSuppress `ANN000`-level errors for dummy arguments, defined as `_`.\n\nDefault: `False`\n\n### `--allow-untyped-defs`: `bool`\nSuppress all errors for dynamically typed functions. A function is considered dynamically typed if it does not contain any type hints.\n\nDefault: `False`\n\n### `--allow-untyped-nested`: `bool`\nSuppress all errors for dynamically typed nested functions. A function is considered dynamically typed if it does not contain any type hints.\n\nDefault: `False`\n\n### `--mypy-init-return`: `bool`\nAllow omission of a return type hint for `__init__` if at least one argument is annotated. See [mypy's documentation](https://mypy.readthedocs.io/en/stable/class_basics.html?#annotating-init-methods) for additional details.\n\nDefault: `False`\n\n### `--dispatch-decorators`: `list[str]`\nComma-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.\n\nDecorators are matched based on their attribute name. For example, `\"singledispatch\"` will match any of the following:\n  * `import functools; @functools.singledispatch`\n  * `import functools as <alias>; @<alias>.singledispatch`\n  * `from functools import singledispatch; @singledispatch`\n\n**NOTE:** Deeper imports, such as `a.b.singledispatch` are not supported.\n\nSee: [Generic Functions](#generic-functions) for additional information.\n\nDefault: `\"singledispatch, singledispatchmethod\"`\n\n### `--overload-decorators`: `list[str]`\nComma-separated list of decorators flake8-annotations should consider as [`typing.overload`](https://docs.python.org/3/library/typing.html#typing.overload) decorators.\n\nDecorators are matched based on their attribute name. For example, `\"overload\"` will match any of the following:\n  * `import typing; @typing.overload`\n  * `import typing as <alias>; @<alias>.overload`\n  * `from typing import overload; @overload`\n\n**NOTE:** Deeper imports, such as `a.b.overload` are not supported.\n\nSee: [The `typing.overload` Decorator](#the-typingoverload-decorator) for additional information.\n\nDefault: `\"overload\"`\n\n### `--allow-star-arg-any`\nSuppress `ANN401` for dynamically typed `*args` and `**kwargs`.\n\nDefault: `False`\n\n### `--respect-type-ignore`\nSuppress linting errors for functions annotated with a `# type: ignore` comment.\n\n**NOTE:** Type ignore tags are not considered, e.g. `# type: ignore[arg-type]` is treated the same as `# type: ignore`.\n\nDefault: `False`\n\n\n## Generic Functions\nPer the Python Glossary, a [generic function](https://docs.python.org/3/glossary.html#term-generic-function) is defined as:\n\n> 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.\n\nIn the standard library we have some examples of decorators for implementing these generic functions: [`functools.singledispatch`](https://docs.python.org/3/library/functools.html#functools.singledispatch) and [`functools.singledispatchmethod`](https://docs.python.org/3/library/functools.html#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.\n\nFor example, this code:\n\n```py\nimport functools\n\n@functools.singledispatch\ndef foo(a):\n    print(a)\n\n@foo.register\ndef _(a: list) -> None:\n    for idx, thing in enumerate(a):\n        print(idx, thing)\n```\n\nWill not raise any linting errors for `foo`.\n\nDecorator(s) to treat as defining generic functions may be specified by the [`--dispatch-decorators`](#--dispatch-decorators-liststr) configuration option.\n\n## The `typing.overload` Decorator\nPer the [`typing`](https://docs.python.org/3/library/typing.html#typing.overload) documentation:\n\n> 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).\n\nIn the spirit of the purpose of this decorator, errors for missing annotations for non-`@overload`-decorated functions are ignored if they meet this criteria.\n\nFor example, this code:\n\n```py\nimport typing\n\n\n@typing.overload\ndef foo(a: int) -> int:\n    ...\n\ndef foo(a):\n    ...\n```\n\nWill not raise linting errors for missing annotations for the arguments & return of the non-decorated `foo` definition.\n\nDecorator(s) to treat as `typing.overload` may be specified by the [`--overload-decorators`](#--overload-decorators-liststr) configuration option.\n\n## Dynamic Typing Caveats\nSupport is only provided for the following patterns:\n  * `from typing import any; foo: Any`\n  * `import typing; foo: typing.Any`\n  * `import typing as <alias>; foo: <alias>.Any`\n\nNested dynamic types (e.g. `typing.Tuple[typing.Any]`) and redefinition (e.g. `from typing import Any as Foo`) will not be identified.\n\n## Contributing\n### Python Version Support\nA best attempt is made to support Python versions until they reach EOL, after which support will be formally dropped by the next minor or major release of this package, whichever arrives first. The status of Python versions can be found [here](https://devguide.python.org/versions/).\n\n### Development Environment\nThis project uses [Poetry](https://python-poetry.org/) 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:\n\n```bash\n$ poetry install\n```\n\nNote: 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.\n\nA [pre-commit](https://pre-commit.com) configuration is also provided to create a pre-commit hook so linting errors aren't committed:\n\n```bash\n$ pre-commit install\n```\n\n### Testing & Coverage\nA [pytest](https://docs.pytest.org/en/latest/) suite is provided, with coverage reporting from [pytest-cov](https://github.com/pytest-dev/pytest-cov). A [tox](https://github.com/tox-dev/tox/) configuration is provided to test across all supported versions of Python. Testing will be skipped for Python versions that cannot be found.\n\n```bash\n$ tox\n```\n\nDetails on missing coverage, including in the test suite, is provided in the report to allow the user to generate additional tests for full coverage.\n\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Flake8 Type Annotation Checks",
    "version": "3.1.0",
    "project_urls": {
        "Homepage": "https://github.com/sco1/flake8-annotations",
        "Issue Tracker": "https://github.com/sco1/flake8-annotations/issues",
        "Repository": "https://github.com/sco1/flake8-annotations"
    },
    "split_keywords": [],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "4db420e52a96f7f6d744303145ae55ac747ed1163ef2358a5bd42f28c21abdaa",
                "md5": "bf1d27d820ea9b905942f4ecf5bad446",
                "sha256": "aa4660bedaa1aff4a5220e92c4469188fbd6e463a21d9a7bad60d1cde42b25bb"
            },
            "downloads": -1,
            "filename": "flake8_annotations-3.1.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "bf1d27d820ea9b905942f4ecf5bad446",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8.1",
            "size": 16818,
            "upload_time": "2024-05-06T18:48:00",
            "upload_time_iso_8601": "2024-05-06T18:48:00.195867Z",
            "url": "https://files.pythonhosted.org/packages/4d/b4/20e52a96f7f6d744303145ae55ac747ed1163ef2358a5bd42f28c21abdaa/flake8_annotations-3.1.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "c29eb7d8b9c75987da2cd57244d90b97887ff3db0778638b4c0ef49ae98b9c0d",
                "md5": "9cb06c34ef31d1d47048945aea7aca97",
                "sha256": "e1a2f0d0190aa20b8621e8d899a6d8e27a05650ae0717765a5c857d71cd0359e"
            },
            "downloads": -1,
            "filename": "flake8_annotations-3.1.0.tar.gz",
            "has_sig": false,
            "md5_digest": "9cb06c34ef31d1d47048945aea7aca97",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8.1",
            "size": 19892,
            "upload_time": "2024-05-06T18:48:02",
            "upload_time_iso_8601": "2024-05-06T18:48:02.477741Z",
            "url": "https://files.pythonhosted.org/packages/c2/9e/b7d8b9c75987da2cd57244d90b97887ff3db0778638b4c0ef49ae98b9c0d/flake8_annotations-3.1.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-05-06 18:48:02",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "sco1",
    "github_project": "flake8-annotations",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "tox": true,
    "lcname": "flake8-annotations"
}
        
Elapsed time: 2.14979s