Respect abc decorators when classifying function types (#5315)

Closes #5307.
This commit is contained in:
Charlie Marsh 2023-06-22 15:52:36 -04:00 committed by GitHub
parent 5f88ff8a96
commit cdbd0bd5cd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 55 additions and 32 deletions

View file

@ -1,4 +1,4 @@
from abc import ABCMeta
import abc
import pydantic
@ -19,6 +19,10 @@ class Class:
def class_method(cls):
pass
@abc.abstractclassmethod
def abstract_class_method(cls):
pass
@staticmethod
def static_method(x):
return x
@ -41,7 +45,7 @@ class Class:
...
class MetaClass(ABCMeta):
class MetaClass(abc.ABCMeta):
def bad_method(self):
pass

View file

@ -1,4 +1,4 @@
from abc import ABCMeta
import abc
import pydantic
@ -34,6 +34,23 @@ class Class:
def stillBad(cls, my_field: str) -> str:
pass
@classmethod
def badAllowed(cls):
pass
@classmethod
def stillBad(cls):
pass
@abc.abstractclassmethod
def badAllowed(cls):
pass
@abc.abstractclassmethod
def stillBad(cls):
pass
class PosOnlyClass:
def badAllowed(this, blah, /, self, something: str):
pass

View file

@ -18,29 +18,29 @@ N805.py:12:30: N805 First argument of a method should be named `self`
13 | pass
|
N805.py:27:15: N805 First argument of a method should be named `self`
|
26 | @pydantic.validator
27 | def lower(cls, my_field: str) -> str:
| ^^^ N805
28 | pass
|
N805.py:31:15: N805 First argument of a method should be named `self`
|
30 | @pydantic.validator("my_field")
30 | @pydantic.validator
31 | def lower(cls, my_field: str) -> str:
| ^^^ N805
32 | pass
|
N805.py:60:29: N805 First argument of a method should be named `self`
N805.py:35:15: N805 First argument of a method should be named `self`
|
58 | pass
59 |
60 | def bad_method_pos_only(this, blah, /, self, something: str):
34 | @pydantic.validator("my_field")
35 | def lower(cls, my_field: str) -> str:
| ^^^ N805
36 | pass
|
N805.py:64:29: N805 First argument of a method should be named `self`
|
62 | pass
63 |
64 | def bad_method_pos_only(this, blah, /, self, something: str):
| ^^^^ N805
61 | pass
65 | pass
|

View file

@ -18,13 +18,13 @@ N805.py:12:30: N805 First argument of a method should be named `self`
13 | pass
|
N805.py:60:29: N805 First argument of a method should be named `self`
N805.py:64:29: N805 First argument of a method should be named `self`
|
58 | pass
59 |
60 | def bad_method_pos_only(this, blah, /, self, something: str):
62 | pass
63 |
64 | def bad_method_pos_only(this, blah, /, self, something: str):
| ^^^^ N805
61 | pass
65 | pass
|

View file

@ -35,13 +35,13 @@ N805.py:34:18: N805 First argument of a method should be named `self`
35 | pass
|
N805.py:41:18: N805 First argument of a method should be named `self`
N805.py:58:18: N805 First argument of a method should be named `self`
|
39 | pass
40 |
41 | def stillBad(this, blah, /, self, something: str):
56 | pass
57 |
58 | def stillBad(this, blah, /, self, something: str):
| ^^^^ N805
42 | pass
59 | pass
|

View file

@ -35,8 +35,10 @@ pub fn classify(
semantic
.resolve_call_path(map_callable(&decorator.expression))
.map_or(false, |call_path| {
matches!(call_path.as_slice(), ["", "staticmethod"])
|| staticmethod_decorators
matches!(
call_path.as_slice(),
["", "staticmethod"] | ["abc", "abstractstaticmethod"]
) || staticmethod_decorators
.iter()
.any(|decorator| call_path == from_qualified_name(decorator))
})
@ -55,7 +57,7 @@ pub fn classify(
|| decorator_list.iter().any(|decorator| {
// The method is decorated with a class method decorator (like `@classmethod`).
semantic.resolve_call_path(map_callable(&decorator.expression)).map_or(false, |call_path| {
matches!(call_path.as_slice(), ["", "classmethod"]) ||
matches!(call_path.as_slice(), ["", "classmethod"] | ["abc", "abstractclassmethod"]) ||
classmethod_decorators
.iter()
.any(|decorator| call_path == from_qualified_name(decorator))