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

PLE1520 false positive when using singledispatchmethod with staticmethod #10619

Closed
ForeverProglamer opened this issue Mar 26, 2024 · 1 comment · Fixed by #10637
Closed

PLE1520 false positive when using singledispatchmethod with staticmethod #10619

ForeverProglamer opened this issue Mar 26, 2024 · 1 comment · Fixed by #10637
Assignees
Labels
bug Something isn't working

Comments

@ForeverProglamer
Copy link

Ruff version: ruff 0.3.4.
Python version: Python 3.12.2.
Code to reproduce a bug:

from functools import singledispatch, singledispatchmethod


class Foo:
    @singledispatchmethod
    @staticmethod
    def bar(value):
        raise NotImplementedError() 

    @bar.register
    @staticmethod
    def _(value: int) -> int:
        return 42 * value

    def method(self) -> int:
        return self.bar(2)


print(Foo().method())

Command invoked to lint the code: ruff check --isolated --preview --select=PL main.py.

main.py:5:5: PLE1520 `@singledispatchmethod` decorator should not be used on non-method functions
  |
4 | class Foo:
5 |     @singledispatchmethod
  |     ^^^^^^^^^^^^^^^^^^^^^ PLE1520
6 |     @staticmethod
7 |     def bar(value):
  |
  = help: Replace with `@singledispatch`

Running this code outputs 84. However, if you replace @singledispatchmethod with @singledispatch as Ruff suggests, and then run the code, you will get an error:

  File "/home/ebubuntu/projects/test/ruff/main.py", line 19, in <module>
    print(Foo().method())
          ^^^^^^^^^^^^^^
  File "/home/ebubuntu/projects/test/ruff/main.py", line 16, in method
    return self.bar(2)
           ^^^^^^^^^^^
  File "/home/ebubuntu/.pyenv/versions/3.12.2/lib/python3.12/functools.py", line 909, in wrapper
    return dispatch(args[0].__class__)(*args, **kw)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: Foo.bar() takes 1 positional argument but 2 were given

Python docs on singledispatchmethod states:

@singledispatchmethod supports nesting with other decorators such as @classmethod. ... The same pattern can be used for other similar decorators: @staticmethod, @abstractmethod, and others.

@AlexWaygood
Copy link
Member

This issue is interesting because our behaviour is currently consistent with pylint's here. However, we discussed this internally, and we agree that the rule is indeed behaving in quite an odd way right now -- we think both pylint's behaviour and ruff's behaviour are both incorrect currently.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
3 participants