Skip to content

Commit 8768d42

Browse files
authored
Merge pull request #545 from asottile/skip-staticmethod
don't rewrite old-super for staticmethods
2 parents a2f517f + 76f6a74 commit 8768d42

2 files changed

Lines changed: 29 additions & 0 deletions

File tree

pyupgrade/_plugins/legacy.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from typing import List
99
from typing import Set
1010
from typing import Tuple
11+
from typing import Union
1112

1213
from tokenize_rt import Offset
1314
from tokenize_rt import Token
@@ -25,6 +26,7 @@
2526

2627
FUNC_TYPES = (ast.Lambda, ast.FunctionDef, ast.AsyncFunctionDef)
2728
NON_LAMBDA_FUNC_TYPES = (ast.FunctionDef, ast.AsyncFunctionDef)
29+
NonLambdaFuncTypes_T = Union[ast.FunctionDef, ast.AsyncFunctionDef]
2830

2931

3032
def _fix_yield(i: int, tokens: List[Token]) -> None:
@@ -44,6 +46,14 @@ def _is_simple_base(base: ast.AST) -> bool:
4446
)
4547

4648

49+
def _is_staticmethod_decorated(node: NonLambdaFuncTypes_T) -> bool:
50+
for decorator in node.decorator_list:
51+
if isinstance(decorator, ast.Name) and decorator.id == 'staticmethod':
52+
return True
53+
else:
54+
return False
55+
56+
4757
class Scope:
4858
def __init__(self, node: ast.AST) -> None:
4959
self.node = node
@@ -127,6 +137,7 @@ def visit_Call(self, node: ast.Call) -> None:
127137
isinstance(self._scopes[-1].node, NON_LAMBDA_FUNC_TYPES) and
128138
node.func.attr == self._scopes[-1].node.name and
129139
node.func.attr != '__new__' and
140+
not _is_staticmethod_decorated(self._scopes[-1].node) and
130141
len(self._scopes[-1].node.args.args) >= 1 and
131142
node.args[0].id == self._scopes[-1].node.args.args[0].arg and
132143
# the function is an attribute of the contained class name

tests/features/super_test.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,13 @@ def test_fix_super(s, expected):
188188
' return tuple.__new__(cls, (arg,))\n',
189189
id='super() does not work properly for __new__',
190190
),
191+
pytest.param(
192+
'class C(B):\n'
193+
' @staticmethod\n'
194+
' def f(arg):\n'
195+
' return B.f(arg)\n',
196+
id='skip staticmethod',
197+
),
191198
),
192199
)
193200
def test_old_style_class_super_noop(s):
@@ -207,6 +214,17 @@ def test_old_style_class_super_noop(s):
207214
' super().f()\n'
208215
' super().f(arg, arg)\n',
209216
),
217+
pytest.param(
218+
'class C(B):\n'
219+
' @classmethod\n'
220+
' def f(cls):\n'
221+
' B.f(cls)\n',
222+
'class C(B):\n'
223+
' @classmethod\n'
224+
' def f(cls):\n'
225+
' super().f()\n',
226+
id='@classmethod',
227+
),
210228
pytest.param(
211229
'class C(B):\n'
212230
' def f(self, a):\n'

0 commit comments

Comments
 (0)