Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

F811 (redefinition of unused variable) incorrectly triggered with @overload decorator #320

Closed
bartvm opened this issue Dec 15, 2017 · 15 comments

Comments

@bartvm
Copy link

bartvm commented Dec 15, 2017

PEP 484 introduced the @overload decorator for type annotations.

[...] a series of @overload-decorated definitions must be followed by exactly one non-@overload-decorated definition (for the same function/method). The @overload-decorated definitions are for the benefit of the type checker only, since they will be overwritten by the non-@overload-decorated definition, while the latter is used at runtime but should be ignored by a type checker.

The following should pass PyFlakes without errors, but currently triggers F811 errors:

from typing import overload


@overload
def utf8(value: None) -> None:
    pass


@overload
def utf8(value: bytes) -> bytes:
    pass


@overload
def utf8(value: str) -> bytes:
    pass


def utf8(value):
    pass  # actual implementation
test.py:9:1: F811 redefinition of unused 'utf8' from line 4
test.py:14:1: F811 redefinition of unused 'utf8' from line 9
test.py:19:1: F811 redefinition of unused 'utf8' from line 14
@tscholak
Copy link

facing the same issue. do you have a workaround?

@bartvm
Copy link
Author

bartvm commented Feb 13, 2018

Added this to .pydocstyle

[pydocstyle]
ignore-decorators = overload
We ended up adding `# noqa: F811` comments.

@sigmavirus24
Copy link
Member

How does pydocstyle config fix a pyflakes bug?

@asottile
Copy link
Member

I took a stab at this: #371

@feisuzhu
Copy link

feisuzhu commented Mar 4, 2019

Hi, it's good to see #371 solved this partially, but overloads on classes is still incorrectly triggered

import typing
from typing import overload


class Foo:
    @overload
    def f(self, s):  # type: (None) -> None
        pass

    @overload
    def f(self, s):  # type: (int) -> int
        pass

    def f(self, s):
        return s

    @typing.overload
    def g(self, s):  # type: (None) -> None
        pass

    @typing.overload
    def g(self, s):  # type: (int) -> int
        pass

    def g(self, s):
        return s
☁  shm  pyflakes a.py 
a.py:11: redefinition of unused 'f' from line 6
a.py:16: redefinition of unused 'f' from line 10
☁  shm  pyflakes --version
2.1.1 Python 3.6.7 on Linux

I'm now working around this by using full typing.overload name

@asottile
Copy link
Member

asottile commented Mar 4, 2019

@feisuzhu try master, I've already fixed this: #435

@eellison
Copy link

eellison commented Aug 6, 2019

I still have this issue when the overload decorator is wrapped by another decorator.

def my_decorator(func):
    return typing.overload(func)

@my_decorator
def utf8(value: None) -> None:
    pass

@my_decorator
def utf8(value: bytes) -> bytes:
    pass

def utf8(value):
    pass  # actual implementation

@asottile
Copy link
Member

asottile commented Aug 6, 2019

that's not possible to detect statically -- I'd suggest not doing that (I don't think mypy can detect that either)

I'd suggest explicitly using the overload decorator

@eellison
Copy link

eellison commented Aug 6, 2019

Gotcha. I don't think this works either.

from typing import overload

def my_decorator(func):
    return func

@overload
@my_decorator
def utf8(value: None) -> None:
    pass

@overload
@my_decorator
def utf8(value: bytes) -> bytes:
    pass

def utf8(value):
    pass  # actual implementation

@asottile
Copy link
Member

asottile commented Aug 6, 2019

Have you tried on master? it works for me

@asottile
Copy link
Member

asottile commented Aug 6, 2019

actually, it even works with the released version of pyflakes so you're probably on an old one

@eellison
Copy link

eellison commented Aug 6, 2019

This is my version info that doesn't work:

3.7.8 (flake8-comprehensions: 2.1.0, flake8-mypy: 17.8.0, mccabe: 0.6.1, pycodestyle: 2.5.0, pyflakes: 2.1.1) CPython 3.6.8 on Linux

What do you think about counting a decorator as a use of a function? Edit: the redefinition error would still exist even if the unused wouldn't

@asottile
Copy link
Member

asottile commented Aug 6, 2019

actually, I'm wrong about it being already released -- it is fixed on master though, please try that and confirm

@asottile
Copy link
Member

asottile commented Aug 6, 2019

see #435

@eellison
Copy link

eellison commented Aug 6, 2019

yea works on master, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants