UseClsInClassmethodRule
Enforces using cls
as the first argument in a @classmethod
.
Message
When using @classmethod, the first argument must be cls.
Has Autofix: Yes
VALID Code Examples
# 1:
class foo:
# classmethod with cls first arg.
@classmethod
def cm(cls, a, b, c):
pass
# 2:
class foo:
# non-classmethod with non-cls first arg.
def nm(self, a, b, c):
pass
# 3:
class foo:
# staticmethod with non-cls first arg.
@staticmethod
def sm(a):
pass
INVALID Code Examples
# 1:
class foo:
# No args at all.
@classmethod
def cm():
pass
Autofix:
---
+++
@@ -2,5 +2,5 @@
class foo:
# No args at all.
@classmethod
- def cm():
+ def cm(cls):
pass
# 2:
class foo:
# Single arg + reference.
@classmethod
def cm(a):
return a
Autofix:
---
+++
@@ -2,5 +2,5 @@
class foo:
# Single arg + reference.
@classmethod
- def cm(a):
- return a
+ def cm(cls):
+ return cls
# 3:
class foo:
# Another "cls" exists: do not autofix.
@classmethod
def cm(a):
cls = 2
# 4:
class foo:
# Multiple args + references.
@classmethod
async def cm(a, b):
b = a
b = a.__name__
Autofix:
---
+++
@@ -2,6 +2,6 @@
class foo:
# Multiple args + references.
@classmethod
- async def cm(a, b):
- b = a
- b = a.__name__
+ async def cm(cls, b):
+ b = cls
+ b = cls.__name__
# 5:
class foo:
# Do not replace in nested scopes.
@classmethod
async def cm(a, b):
b = a
b = lambda _: a.__name__
def g():
return a.__name__
# Same-named vars in sub-scopes should not be replaced.
b = [a for a in [1,2,3]]
def f(a):
return a + 1
Autofix:
---
+++
@@ -2,11 +2,11 @@
class foo:
# Do not replace in nested scopes.
@classmethod
- async def cm(a, b):
- b = a
- b = lambda _: a.__name__
+ async def cm(cls, b):
+ b = cls
+ b = lambda _: cls.__name__
def g():
- return a.__name__
+ return cls.__name__
# Same-named vars in sub-scopes should not be replaced.
b = [a for a in [1,2,3]]
# 6:
# Do not replace in surrounding scopes.
a = 1
class foo:
a = 2
def im(a):
a = a
@classmethod
def cm(a):
a[1] = foo.cm(a=a)
Autofix:
---
+++
@@ -9,5 +9,5 @@
a = a
@classmethod
- def cm(a):
- a[1] = foo.cm(a=a)
+ def cm(cls):
+ cls[1] = foo.cm(a=cls)
# 7:
def another_decorator(x): pass
class foo:
# Multiple decorators.
@another_decorator
@classmethod
@another_decorator
async def cm(a, b, c):
pass
Autofix:
---
+++
@@ -6,5 +6,5 @@
@another_decorator
@classmethod
@another_decorator
- async def cm(a, b, c):
+ async def cm(cls, b, c):
pass