Skip to content

Commit

Permalink
Improve @overload detection (#435)
Browse files Browse the repository at this point in the history
* Support @overload mixed with other decorators

* Detect @overload not just at module scope
  • Loading branch information
asottile authored and sigmavirus24 committed Mar 1, 2019
1 parent 6ba3f8e commit 232cb1d
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 8 deletions.
25 changes: 17 additions & 8 deletions pyflakes/checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -530,14 +530,21 @@ def getNodeName(node):
return node.name


def is_typing_overload(value, scope):
def is_typing_overload(value, scope_stack):
def name_is_typing_overload(name): # type: (str) -> bool
for scope in reversed(scope_stack):
if name in scope:
return (
isinstance(scope[name], ImportationFrom) and
scope[name].fullName == 'typing.overload'
)
else:
return False

def is_typing_overload_decorator(node):
return (
(
isinstance(node, ast.Name) and
node.id in scope and
isinstance(scope[node.id], ImportationFrom) and
scope[node.id].fullName == 'typing.overload'
isinstance(node, ast.Name) and name_is_typing_overload(node.id)
) or (
isinstance(node, ast.Attribute) and
isinstance(node.value, ast.Name) and
Expand All @@ -548,8 +555,10 @@ def is_typing_overload_decorator(node):

return (
isinstance(value.source, ast.FunctionDef) and
len(value.source.decorator_list) == 1 and
is_typing_overload_decorator(value.source.decorator_list[0])
any(
is_typing_overload_decorator(dec)
for dec in value.source.decorator_list
)
)


Expand Down Expand Up @@ -888,7 +897,7 @@ def addBinding(self, node, value):
node, value.name, existing.source)
elif not existing.used and value.redefines(existing):
if value.name != '_' or isinstance(existing, Importation):
if not is_typing_overload(existing, self.scope):
if not is_typing_overload(existing, self.scopeStack):
self.report(messages.RedefinedWhileUnused,
node, value.name, existing.source)

Expand Down
35 changes: 35 additions & 0 deletions pyflakes/test/test_type_annotations.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,41 @@ def g(s):
return s
""")

def test_overload_with_multiple_decorators(self):
self.flakes("""
from typing import overload
dec = lambda f: f
@dec
@overload
def f(x): # type: (int) -> int
pass
@dec
@overload
def f(x): # type: (str) -> str
pass
@dec
def f(x): return x
""")

def test_overload_in_class(self):
self.flakes("""
from typing import overload
class C:
@overload
def f(self, x): # type: (int) -> int
pass
@overload
def f(self, x): # type: (str) -> str
pass
def f(self, x): return x
""")

def test_not_a_typing_overload(self):
"""regression test for @typing.overload detection bug in 2.1.0"""
self.flakes("""
Expand Down

0 comments on commit 232cb1d

Please sign in to comment.