[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:
- The function node is either a class method or classmethod
- 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
)