Skip to content

Releases: sco1/flake8-annotations

Release v2.6.0

05 Mar 22:04
9058f8f
Compare
Choose a tag to compare

Changelog

[v2.6.0]

Added

  • #98 Add --dispatch-decorators to support suppression of all errors from functions decorated by decorators such as functools.singledispatch and functools.singledispatchmethod.
  • #99 Add --overload-decorators to support generic aliasing of the typing.overload decorator.

Fixed

  • #106 Fix incorrect parsing of multiline docstrings with less than two lines of content, causing incorrect line numbers for yielded errors in Python versions prior to 3.8

Additional Details

Generic Functions

Per #98, the functools.singledispatch and functools.singledispatchmethod decorators transform a function into a single-dispatch generic function.

For example:

import functools

@functools.singledispatch
def foo(a):
    print(a)

@foo.register
def _(a: list) -> None:
    for idx, thing in enumerate(a):
        print(idx, thing)

Is correctly annotated but would previously yield linting errors for foo. In the spirit of the purpose of these decorators, linting errors are now suppressed for functions decorated with these decorators. The --dispatch-decorators configuration option has been added, which specifies a comma-separated list of decorators to be considered as dispatch decorators.

Decorators are matched based on their attribute name. For example, "singledispatch" will match any of the following:

  • import functools; @functools.singledispatch
  • import functools as fnctls; @fnctls.singledispatch
  • from functools import singledispatch; @singledispatch

By default, linting errors are suppressed for functions decorated by singledispatch or singledispatchmethod.

typing.overload decorator aliasing

Per #99, handling of the typing.overload has been made generic, removing the caveat from the initial implementation. The --overload-decorators configuration option has been added, which specifies a comma-separated list of decorators to be considered as typing.overload decorators.

Decorators are now matched based on their attribute name. For example, "overload" will match any of the following:

  • import typing; @typing.overload
  • import typing as t; @t.overload
  • from typing import overload; @overload

By default, linting errors are suppressed for functions decorated by overload, which should be a transparent change from v2.4 (#97).

Release v2.5.0

04 Jan 15:15
8fe98cc
Compare
Choose a tag to compare

Changelog

[v2.5.0]

Added

  • #103 add --allow-untyped-nested to suppress all errors from dynamically typted nested functions. A function is considered dynamically typed if it does not contain any type hints.

Additional Details

Per #102, nested functions can fall into an interesting spot semantically for a project. They're distinct enough from private/secret functions that one may not want to strictly enforce annotation (e.g. decorator definitions) but there does not exist a mechanism to do so without either noqa or just allowing all dynamically typed functions (via --allow-untyped-defs). The --allow-untyped-nested flag allows for this stricter subset of dynamic functions.

Release v2.4.1

29 Sep 16:28
8df66f4
Compare
Choose a tag to compare

[v2.4.1]

Fixed

  • #100 Fix incorrect positioning of posonlyargs in the Function argument list, causing incorrect classification of the type of missing argument.

Release v2.4.0

09 Sep 13:37
f2487f9
Compare
Choose a tag to compare

[v2.4.0]

Fixed

  • #92 Fix inconsistent linting behavior between function-level type comments and their equivalent PEP 3107-style function annotations of class methods and classmethods.
  • #94 Fix improper handling of the closing definition in a series of typing.overload decorated functions.

Additional Details

Function-level type comment changes

Per #92, there exists a discrepancy in behavior between linting of functions with PEP 3107-style annotations and PEP 484-style function-level type comments. Because PEP 484 does not describe a method to provide partial function-level type comments, there is a potential for ambiguity in the context of both class methods and classmethods when aligning type comments to method arguments.

These two class methods, for example, should lint equivalently:

    def bar(self, a):
        # type: (int) -> int
        ...

    def bar(self, a: int) -> int
        ...

When this example type comment is parsed by ast and then matched with the method's arguments, it associates the int hint to self rather than a, so a dummy hint needs to be provided in situations where self or class are not hinted in the type comment in order to achieve equivalent linting results to PEP-3107 style annotations.

A dummy ast.Ellipses constant is injected into the parsed node if the following criteria are met:

  1. The function node is either a class method or classmethod
  2. The number of hinted args is at least 1 less than the number of function args

typing.overload decorator handling

Per #94, the typing.overload was being handled too literally (aka: ignored) by the linter, resulting in emitted linting errors that do not align with the purpose of the decorator.

For example, this code:

import typing


@typing.overload
def foo(a: int) -> int:
    ...

def foo(a):
    ...

Would raise linting errors for missing annotations for the arguments & return of the non-decorated foo definition; this interpretation disagrees with the purpose of the decorator.

Per the documentation:

A series of @overload-decorated definitions must be followed by exactly one non-@overload-decorated definition (for the same function/method)

Errors for missing annotations for non-@overload-decorated functions are now ignored if they meet this criteria.

NOTE: If importing directly, the typing.overload decorator will not be recognized if it is imported with an alias (e.g. from typing import overload as please_dont_do_this). Aliasing of the typing module is supported (e.g. import typing as t; @t.overload)

Release v2.3.0

12 Jul 00:04
2c5c7a4
Compare
Choose a tag to compare

[v2.3.0]

Added

  • #87 Add --mypy-init-return to allow omission of a return type hint for __init__ if at least one argument is annotated.

Additional Details

To help provide compatibility with Mypy for maintainers that wish to do so, the --mypy-init-return flag has been introduced to mimic Mypy's allowance for the omission of return type hints for __init__ methods that are not dynamically typed (at least one argument is annotated). With this flag set, ANN200 level errors will be suppressed for __init__ methods if at least one argument is explicitly annotated.

For example, from Mypy's documentation:

class C1:  # Return annotated
    def __init__(self) -> None:
        self.var = 42

class C2:  # Return annotated
    def __init__(self, arg: int):
        self.var = arg

class C3:
    def __init__(self):  # Return not annotated
        # This body is not type checked
        self.var = 42 + 'abc'

NOTE: By default, Mypy does not enforce annotations for self in class methods, so to completely mimic Mypy's behavior with flake8-annotations ANN101 will need to be added to the repository's ignored linting codes.

See Mypy's documentation for additional details: https://mypy.readthedocs.io/en/stable/class_basics.html?#annotating-init-methods

Release v2.2.1

10 Jul 19:11
d4b6d18
Compare
Choose a tag to compare

[v2.2.1]

Fixed

  • #89 Revert change to Python version pinning to prevent unnecessary locking headaches

Release v2.2.0

06 Jul 18:11
63ad381
Compare
Choose a tag to compare

[v2.2.0]

Added

  • #87 Add --allow-untyped-defs to suppress all errors from dynamically typed functions. A function is considered dynamically typed if it does not contain any type hints.

Fixed

  • #77, #81 Fix incorrect return error locations in the presence of a multiline docstring containing colon(s)
  • #81 Fix incorrect return error locations for single-line function definitions
  • Fix incorrectly pinned project specifications

Release v2.1.0

11 Apr 18:34
1fb0681
Compare
Choose a tag to compare

v2.1.0

Added

  • #68 Add --suppress-dummy-args configuration option to suppress ANN000 level errors for dummy arguments, defined as "_"

Release v2.0.1

01 Mar 22:35
875ca7f
Compare
Choose a tag to compare

v2.0.1

Added

  • #71 Add pep8-naming to linting toolchain
  • Expand pre-commit hooks
    • Add black
    • Add check-merge-conflict
    • Add check-toml
    • Add check-yaml
    • Add end-of-file-fixer
    • Add mixed-line-ending
    • Add python-check-blanket-noqa

Changed

  • Add argument names to Argument and Function __repr__ methods to make the string more helpful to read

Fixed

  • #70 Fix incorrect column index for missing return annotations when other annotations are present on the same line of source
  • #69 Fix misclassification of None returning functions when they contained nested functions with non-None returns (thanks @isidentical!)
  • #67 Fix methods of nested classes being improperly classified as "regular" functions (thanks @isidentical!)

Additional Details

The previous approach being taken for nesting as to use a generic_visit() on the node to visit any nested functions. However, from the bugs reported (#67, #69) it was made clear that this approach was too generic & a method for either restricting or keeping track of the depth of this generic visit was required.

Both the FunctionVisitor and ReturnVisitor classes have been rearchitected to keep track of the parent context of the nodes being visited in order to properly classify methods of nested classes and return values of nested functions, respectively.

You can view a full writeup here on discuss.python.org.

Release v2.0.0

11 Feb 20:37
fa11dad
Compare
Choose a tag to compare

[v2.0.0]

Changed

  • #64 Change prefix from TYP to ANN in order to deconflict with flake8-typing-imports

Additional Details

Per #64, due to prefix shadowing of TYP between flake8-annotations and flake8-typing-imports, it's been suggested that the prefix for this repository be changed to ANN so the plugins can coexist peacefully.