Flake8 Annotations Versions Save

Flake8 Type Annotation Checking

2.4.1

3 years ago

[v2.4.1]

Fixed

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

v2.4.0

3 years ago

[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)

v2.3.0

3 years ago

[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

v2.2.1

3 years ago

[v2.2.1]

Fixed

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

v2.2.0

3 years ago

[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

v2.1.0

4 years ago

v2.1.0

Added

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

v2.0.1

4 years ago

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.

v2.0.0

4 years ago

[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.

v1.2.0

4 years ago

[v1.2.0]

Added

  • Add test case for checking whether flake8 invokes our plugin
  • #41 Add --suppress-none-returning configuration option to suppress TYP200 level errors for functions that either lack a return statement or only explicitly return None.
  • Add black as an explicit developer requirement (codebase already adheres to black formatting)

Changed

  • #61 Migrate from Pipenv to Poetry for developer environment setup

Additional Details:

This release adds the --suppress-none-returning configuration option, as requested by #41. If this flag is set, TYP200-level errors are suppressed for functions that meet one of the following criteria:

  • Contain no return statement, or
  • Explicit return statement(s) all return None (explicitly or implicitly).

For example:

def foo():
    """This is a test function."""
    a = 2 + 2
    if a == 4:
        return None
    else:
        return

Will not yield a TYP201 error, with the flag set:

$ flake8 test.py
test.py:1:11: TYP201 Missing return type annotation for public function
$ flake8 test.py --suppress-none-returning
<No output>

And:

def foo():
    """This is a test function."""
    a = 2 + 2
    if a == 4:
        return True
    else:
        return

Will still yield a TYP201 error, with the flag set:

$ flake8 test.py
test.py:1:11: TYP201 Missing return type annotation for public function
$ flake8 test.py --suppress-none-returning
test.py:1:11: TYP201 Missing return type annotation for public function

The default value of this configuration option is False, so this addition should be transparent to existing users.

v1.1.3

4 years ago

[v1.1.3]

Fixed

  • Add missing classifier test cases for POSONLYARGS
  • Re-add the tree argument to the checker so flake8 identifies the plugin as needing to run