Method: pylint.checkers.classes.class_checker.ClassChecker._check_useless_super_delegation
Calls: 1716, Exceptions: 0, Paths: 18Back
Path 1: 1631 calls (0.95)
FunctionDef (1614) AsyncFunctionDef (17)
None (1631)
1def _check_useless_super_delegation(self, function: nodes.FunctionDef) -> None:
2 """Check if the given function node is an useless method override.
3
4 We consider it *useless* if it uses the super() builtin, but having
5 nothing additional whatsoever than not implementing the method at all.
6 If the method uses super() to delegate an operation to the rest of the MRO,
7 and if the method called is the same as the current one, the arguments
8 passed to super() are the same as the parameters that were passed to
9 this method, then the method could be removed altogether, by letting
10 other implementation to take precedence.
11 """
12 if not _is_trivial_super_delegation(function):
13 return
14
15 call: nodes.Call = function.body[0].value
16
17 # Classes that override __eq__ should also override
18 # __hash__, even a trivial override is meaningful
19 if function.name == "__hash__":
20 for other_method in function.parent.mymethods():
21 if other_method.name == "__eq__":
22 return
23
24 # Check values of default args
25 klass = function.parent.frame(future=True)
26 meth_node = None
27 for overridden in klass.local_attr_ancestors(function.name):
28 # get astroid for the searched method
29 try:
30 meth_node = overridden[function.name]
31 except KeyError:
32 # we have found the method but it's not in the local
33 # dictionary.
34 # This may happen with astroid build from living objects
35 continue
36 if (
37 not isinstance(meth_node, nodes.FunctionDef)
38 # If the method have an ancestor which is not a
39 # function then it is legitimate to redefine it
40 or _has_different_parameters_default_value(
41 meth_node.args, function.args
42 )
43 # arguments to builtins such as Exception.__init__() cannot be inspected
44 or (meth_node.args.args is None and function.argnames() != ["self"])
45 ):
46 return
47 break
48
49 # Detect if the parameters are the same as the call's arguments.
50 params = _signature_from_arguments(function.args)
51 args = _signature_from_call(call)
52
53 if meth_node is not None:
54 # Detect if the super method uses varargs and the function doesn't or makes some of those explicit
55 if meth_node.args.vararg and (
56 not function.args.vararg
57 or len(function.args.args) > len(meth_node.args.args)
58 ):
59 return
60
61 def form_annotations(arguments: nodes.Arguments) -> list[str]:
62 annotations = chain(
63 (arguments.posonlyargs_annotations or []), arguments.annotations
64 )
65 return [ann.as_string() for ann in annotations if ann is not None]
66
67 called_annotations = form_annotations(function.args)
68 overridden_annotations = form_annotations(meth_node.args)
69 if called_annotations and overridden_annotations:
70 if called_annotations != overridden_annotations:
71 return
72
73 if (
74 function.returns is not None
75 and meth_node.returns is not None
76 and meth_node.returns.as_string() != function.returns.as_string()
77 ):
78 # Override adds typing information to the return type
79 return
80
81 if _definition_equivalent_to_call(params, args):
82 self.add_message(
83 "useless-parent-delegation",
84 node=function,
85 args=(function.name,),
86 confidence=INFERENCE,
87 )
Path 2: 20 calls (0.01)
FunctionDef (20)
1def _check_useless_super_delegation(self, function: nodes.FunctionDef) -> None:
2 """Check if the given function node is an useless method override.
3
4 We consider it *useless* if it uses the super() builtin, but having
5 nothing additional whatsoever than not implementing the method at all.
6 If the method uses super() to delegate an operation to the rest of the MRO,
7 and if the method called is the same as the current one, the arguments
8 passed to super() are the same as the parameters that were passed to
9 this method, then the method could be removed altogether, by letting
10 other implementation to take precedence.
11 """
12 if not _is_trivial_super_delegation(function):
13 return
14
15 call: nodes.Call = function.body[0].value
16
17 # Classes that override __eq__ should also override
18 # __hash__, even a trivial override is meaningful
19 if function.name == "__hash__":
20 for other_method in function.parent.mymethods():
21 if other_method.name == "__eq__":
22 return
23
24 # Check values of default args
25 klass = function.parent.frame(future=True)
26 meth_node = None
27 for overridden in klass.local_attr_ancestors(function.name):
28 # get astroid for the searched method
29 try:
30 meth_node = overridden[function.name]
31 except KeyError:
32 # we have found the method but it's not in the local
33 # dictionary.
34 # This may happen with astroid build from living objects
35 continue
36 if (
37 not isinstance(meth_node, nodes.FunctionDef)
38 # If the method have an ancestor which is not a
39 # function then it is legitimate to redefine it
40 or _has_different_parameters_default_value(
41 meth_node.args, function.args
42 )
43 # arguments to builtins such as Exception.__init__() cannot be inspected
44 or (meth_node.args.args is None and function.argnames() != ["self"])
45 ):
46 return
47 break
48
49 # Detect if the parameters are the same as the call's arguments.
50 params = _signature_from_arguments(function.args)
51 args = _signature_from_call(call)
52
53 if meth_node is not None:
54 # Detect if the super method uses varargs and the function doesn't or makes some of those explicit
55 if meth_node.args.vararg and (
56 not function.args.vararg
57 or len(function.args.args) > len(meth_node.args.args)
58 ):
59 return
60
61 def form_annotations(arguments: nodes.Arguments) -> list[str]:
62 annotations = chain(
63 (arguments.posonlyargs_annotations or []), arguments.annotations
64 )
65 return [ann.as_string() for ann in annotations if ann is not None]
66
67 called_annotations = form_annotations(function.args)
68 overridden_annotations = form_annotations(meth_node.args)
69 if called_annotations and overridden_annotations:
70 if called_annotations != overridden_annotations:
71 return
72
73 if (
74 function.returns is not None
75 and meth_node.returns is not None
76 and meth_node.returns.as_string() != function.returns.as_string()
77 ):
78 # Override adds typing information to the return type
79 return
80
81 if _definition_equivalent_to_call(params, args):
82 self.add_message(
83 "useless-parent-delegation",
84 node=function,
85 args=(function.name,),
86 confidence=INFERENCE,
87 )
Path 3: 16 calls (0.01)
FunctionDef (16)
None (16)
1def _check_useless_super_delegation(self, function: nodes.FunctionDef) -> None:
2 """Check if the given function node is an useless method override.
3
4 We consider it *useless* if it uses the super() builtin, but having
5 nothing additional whatsoever than not implementing the method at all.
6 If the method uses super() to delegate an operation to the rest of the MRO,
7 and if the method called is the same as the current one, the arguments
8 passed to super() are the same as the parameters that were passed to
9 this method, then the method could be removed altogether, by letting
10 other implementation to take precedence.
11 """
12 if not _is_trivial_super_delegation(function):
13 return
14
15 call: nodes.Call = function.body[0].value
16
17 # Classes that override __eq__ should also override
18 # __hash__, even a trivial override is meaningful
19 if function.name == "__hash__":
20 for other_method in function.parent.mymethods():
21 if other_method.name == "__eq__":
22 return
23
24 # Check values of default args
25 klass = function.parent.frame(future=True)
26 meth_node = None
27 for overridden in klass.local_attr_ancestors(function.name):
28 # get astroid for the searched method
29 try:
30 meth_node = overridden[function.name]
31 except KeyError:
32 # we have found the method but it's not in the local
33 # dictionary.
34 # This may happen with astroid build from living objects
35 continue
36 if (
37 not isinstance(meth_node, nodes.FunctionDef)
38 # If the method have an ancestor which is not a
39 # function then it is legitimate to redefine it
40 or _has_different_parameters_default_value(
41 meth_node.args, function.args
42 )
43 # arguments to builtins such as Exception.__init__() cannot be inspected
44 or (meth_node.args.args is None and function.argnames() != ["self"])
45 ):
46 return
47 break
48
49 # Detect if the parameters are the same as the call's arguments.
50 params = _signature_from_arguments(function.args)
51 args = _signature_from_call(call)
52
53 if meth_node is not None:
54 # Detect if the super method uses varargs and the function doesn't or makes some of those explicit
55 if meth_node.args.vararg and (
56 not function.args.vararg
57 or len(function.args.args) > len(meth_node.args.args)
58 ):
59 return
60
61 def form_annotations(arguments: nodes.Arguments) -> list[str]:
62 annotations = chain(
63 (arguments.posonlyargs_annotations or []), arguments.annotations
64 )
65 return [ann.as_string() for ann in annotations if ann is not None]
66
67 called_annotations = form_annotations(function.args)
68 overridden_annotations = form_annotations(meth_node.args)
69 if called_annotations and overridden_annotations:
70 if called_annotations != overridden_annotations:
71 return
72
73 if (
74 function.returns is not None
75 and meth_node.returns is not None
76 and meth_node.returns.as_string() != function.returns.as_string()
77 ):
78 # Override adds typing information to the return type
79 return
80
81 if _definition_equivalent_to_call(params, args):
82 self.add_message(
83 "useless-parent-delegation",
84 node=function,
85 args=(function.name,),
86 confidence=INFERENCE,
87 )
Path 4: 13 calls (0.01)
FunctionDef (13)
1def _check_useless_super_delegation(self, function: nodes.FunctionDef) -> None:
2 """Check if the given function node is an useless method override.
3
4 We consider it *useless* if it uses the super() builtin, but having
5 nothing additional whatsoever than not implementing the method at all.
6 If the method uses super() to delegate an operation to the rest of the MRO,
7 and if the method called is the same as the current one, the arguments
8 passed to super() are the same as the parameters that were passed to
9 this method, then the method could be removed altogether, by letting
10 other implementation to take precedence.
11 """
12 if not _is_trivial_super_delegation(function):
13 return
14
15 call: nodes.Call = function.body[0].value
16
17 # Classes that override __eq__ should also override
18 # __hash__, even a trivial override is meaningful
19 if function.name == "__hash__":
20 for other_method in function.parent.mymethods():
21 if other_method.name == "__eq__":
22 return
23
24 # Check values of default args
25 klass = function.parent.frame(future=True)
26 meth_node = None
27 for overridden in klass.local_attr_ancestors(function.name):
28 # get astroid for the searched method
29 try:
30 meth_node = overridden[function.name]
31 except KeyError:
32 # we have found the method but it's not in the local
33 # dictionary.
34 # This may happen with astroid build from living objects
35 continue
36 if (
37 not isinstance(meth_node, nodes.FunctionDef)
38 # If the method have an ancestor which is not a
39 # function then it is legitimate to redefine it
40 or _has_different_parameters_default_value(
41 meth_node.args, function.args
42 )
43 # arguments to builtins such as Exception.__init__() cannot be inspected
44 or (meth_node.args.args is None and function.argnames() != ["self"])
45 ):
46 return
47 break
48
49 # Detect if the parameters are the same as the call's arguments.
50 params = _signature_from_arguments(function.args)
51 args = _signature_from_call(call)
52
53 if meth_node is not None:
54 # Detect if the super method uses varargs and the function doesn't or makes some of those explicit
55 if meth_node.args.vararg and (
56 not function.args.vararg
57 or len(function.args.args) > len(meth_node.args.args)
58 ):
59 return
60
61 def form_annotations(arguments: nodes.Arguments) -> list[str]:
62 annotations = chain(
63 (arguments.posonlyargs_annotations or []), arguments.annotations
64 )
65 return [ann.as_string() for ann in annotations if ann is not None]
66
67 called_annotations = form_annotations(function.args)
68 overridden_annotations = form_annotations(meth_node.args)
69 if called_annotations and overridden_annotations:
70 if called_annotations != overridden_annotations:
71 return
72
73 if (
74 function.returns is not None
75 and meth_node.returns is not None
76 and meth_node.returns.as_string() != function.returns.as_string()
77 ):
78 # Override adds typing information to the return type
79 return
80
81 if _definition_equivalent_to_call(params, args):
82 self.add_message(
83 "useless-parent-delegation",
84 node=function,
85 args=(function.name,),
86 confidence=INFERENCE,
87 )
Path 5: 11 calls (0.01)
FunctionDef (11)
1def _check_useless_super_delegation(self, function: nodes.FunctionDef) -> None:
2 """Check if the given function node is an useless method override.
3
4 We consider it *useless* if it uses the super() builtin, but having
5 nothing additional whatsoever than not implementing the method at all.
6 If the method uses super() to delegate an operation to the rest of the MRO,
7 and if the method called is the same as the current one, the arguments
8 passed to super() are the same as the parameters that were passed to
9 this method, then the method could be removed altogether, by letting
10 other implementation to take precedence.
11 """
12 if not _is_trivial_super_delegation(function):
13 return
14
15 call: nodes.Call = function.body[0].value
16
17 # Classes that override __eq__ should also override
18 # __hash__, even a trivial override is meaningful
19 if function.name == "__hash__":
20 for other_method in function.parent.mymethods():
21 if other_method.name == "__eq__":
22 return
23
24 # Check values of default args
25 klass = function.parent.frame(future=True)
26 meth_node = None
27 for overridden in klass.local_attr_ancestors(function.name):
28 # get astroid for the searched method
29 try:
30 meth_node = overridden[function.name]
31 except KeyError:
32 # we have found the method but it's not in the local
33 # dictionary.
34 # This may happen with astroid build from living objects
35 continue
36 if (
37 not isinstance(meth_node, nodes.FunctionDef)
38 # If the method have an ancestor which is not a
39 # function then it is legitimate to redefine it
40 or _has_different_parameters_default_value(
41 meth_node.args, function.args
42 )
43 # arguments to builtins such as Exception.__init__() cannot be inspected
44 or (meth_node.args.args is None and function.argnames() != ["self"])
45 ):
46 return
47 break
48
49 # Detect if the parameters are the same as the call's arguments.
50 params = _signature_from_arguments(function.args)
51 args = _signature_from_call(call)
52
53 if meth_node is not None:
54 # Detect if the super method uses varargs and the function doesn't or makes some of those explicit
55 if meth_node.args.vararg and (
56 not function.args.vararg
57 or len(function.args.args) > len(meth_node.args.args)
58 ):
59 return
60
61 def form_annotations(arguments: nodes.Arguments) -> list[str]:
62 annotations = chain(
63 (arguments.posonlyargs_annotations or []), arguments.annotations
64 )
65 return [ann.as_string() for ann in annotations if ann is not None]
66
67 called_annotations = form_annotations(function.args)
68 overridden_annotations = form_annotations(meth_node.args)
69 if called_annotations and overridden_annotations:
70 if called_annotations != overridden_annotations:
71 return
72
73 if (
74 function.returns is not None
75 and meth_node.returns is not None
76 and meth_node.returns.as_string() != function.returns.as_string()
77 ):
78 # Override adds typing information to the return type
79 return
80
81 if _definition_equivalent_to_call(params, args):
82 self.add_message(
83 "useless-parent-delegation",
84 node=function,
85 args=(function.name,),
86 confidence=INFERENCE,
87 )
Path 6: 8 calls (0.0)
FunctionDef (8)
1def _check_useless_super_delegation(self, function: nodes.FunctionDef) -> None:
2 """Check if the given function node is an useless method override.
3
4 We consider it *useless* if it uses the super() builtin, but having
5 nothing additional whatsoever than not implementing the method at all.
6 If the method uses super() to delegate an operation to the rest of the MRO,
7 and if the method called is the same as the current one, the arguments
8 passed to super() are the same as the parameters that were passed to
9 this method, then the method could be removed altogether, by letting
10 other implementation to take precedence.
11 """
12 if not _is_trivial_super_delegation(function):
13 return
14
15 call: nodes.Call = function.body[0].value
16
17 # Classes that override __eq__ should also override
18 # __hash__, even a trivial override is meaningful
19 if function.name == "__hash__":
20 for other_method in function.parent.mymethods():
21 if other_method.name == "__eq__":
22 return
23
24 # Check values of default args
25 klass = function.parent.frame(future=True)
26 meth_node = None
27 for overridden in klass.local_attr_ancestors(function.name):
28 # get astroid for the searched method
29 try:
30 meth_node = overridden[function.name]
31 except KeyError:
32 # we have found the method but it's not in the local
33 # dictionary.
34 # This may happen with astroid build from living objects
35 continue
36 if (
37 not isinstance(meth_node, nodes.FunctionDef)
38 # If the method have an ancestor which is not a
39 # function then it is legitimate to redefine it
40 or _has_different_parameters_default_value(
41 meth_node.args, function.args
42 )
43 # arguments to builtins such as Exception.__init__() cannot be inspected
44 or (meth_node.args.args is None and function.argnames() != ["self"])
45 ):
46 return
47 break
48
49 # Detect if the parameters are the same as the call's arguments.
50 params = _signature_from_arguments(function.args)
51 args = _signature_from_call(call)
52
53 if meth_node is not None:
54 # Detect if the super method uses varargs and the function doesn't or makes some of those explicit
55 if meth_node.args.vararg and (
56 not function.args.vararg
57 or len(function.args.args) > len(meth_node.args.args)
58 ):
59 return
60
61 def form_annotations(arguments: nodes.Arguments) -> list[str]:
62 annotations = chain(
63 (arguments.posonlyargs_annotations or []), arguments.annotations
64 )
65 return [ann.as_string() for ann in annotations if ann is not None]
66
67 called_annotations = form_annotations(function.args)
68 overridden_annotations = form_annotations(meth_node.args)
69 if called_annotations and overridden_annotations:
70 if called_annotations != overridden_annotations:
71 return
72
73 if (
74 function.returns is not None
75 and meth_node.returns is not None
76 and meth_node.returns.as_string() != function.returns.as_string()
77 ):
78 # Override adds typing information to the return type
79 return
80
81 if _definition_equivalent_to_call(params, args):
82 self.add_message(
83 "useless-parent-delegation",
84 node=function,
85 args=(function.name,),
86 confidence=INFERENCE,
87 )
Path 7: 3 calls (0.0)
FunctionDef (3)
None (3)
1def _check_useless_super_delegation(self, function: nodes.FunctionDef) -> None:
2 """Check if the given function node is an useless method override.
3
4 We consider it *useless* if it uses the super() builtin, but having
5 nothing additional whatsoever than not implementing the method at all.
6 If the method uses super() to delegate an operation to the rest of the MRO,
7 and if the method called is the same as the current one, the arguments
8 passed to super() are the same as the parameters that were passed to
9 this method, then the method could be removed altogether, by letting
10 other implementation to take precedence.
11 """
12 if not _is_trivial_super_delegation(function):
13 return
14
15 call: nodes.Call = function.body[0].value
16
17 # Classes that override __eq__ should also override
18 # __hash__, even a trivial override is meaningful
19 if function.name == "__hash__":
20 for other_method in function.parent.mymethods():
21 if other_method.name == "__eq__":
22 return
23
24 # Check values of default args
25 klass = function.parent.frame(future=True)
26 meth_node = None
27 for overridden in klass.local_attr_ancestors(function.name):
28 # get astroid for the searched method
29 try:
30 meth_node = overridden[function.name]
31 except KeyError:
32 # we have found the method but it's not in the local
33 # dictionary.
34 # This may happen with astroid build from living objects
35 continue
36 if (
37 not isinstance(meth_node, nodes.FunctionDef)
38 # If the method have an ancestor which is not a
39 # function then it is legitimate to redefine it
40 or _has_different_parameters_default_value(
41 meth_node.args, function.args
42 )
43 # arguments to builtins such as Exception.__init__() cannot be inspected
44 or (meth_node.args.args is None and function.argnames() != ["self"])
45 ):
46 return
47 break
48
49 # Detect if the parameters are the same as the call's arguments.
50 params = _signature_from_arguments(function.args)
51 args = _signature_from_call(call)
52
53 if meth_node is not None:
54 # Detect if the super method uses varargs and the function doesn't or makes some of those explicit
55 if meth_node.args.vararg and (
56 not function.args.vararg
57 or len(function.args.args) > len(meth_node.args.args)
58 ):
59 return
60
61 def form_annotations(arguments: nodes.Arguments) -> list[str]:
62 annotations = chain(
63 (arguments.posonlyargs_annotations or []), arguments.annotations
64 )
65 return [ann.as_string() for ann in annotations if ann is not None]
66
67 called_annotations = form_annotations(function.args)
68 overridden_annotations = form_annotations(meth_node.args)
69 if called_annotations and overridden_annotations:
70 if called_annotations != overridden_annotations:
71 return
72
73 if (
74 function.returns is not None
75 and meth_node.returns is not None
76 and meth_node.returns.as_string() != function.returns.as_string()
77 ):
78 # Override adds typing information to the return type
79 return
80
81 if _definition_equivalent_to_call(params, args):
82 self.add_message(
83 "useless-parent-delegation",
84 node=function,
85 args=(function.name,),
86 confidence=INFERENCE,
87 )
Path 8: 2 calls (0.0)
FunctionDef (2)
None (2)
1def _check_useless_super_delegation(self, function: nodes.FunctionDef) -> None:
2 """Check if the given function node is an useless method override.
3
4 We consider it *useless* if it uses the super() builtin, but having
5 nothing additional whatsoever than not implementing the method at all.
6 If the method uses super() to delegate an operation to the rest of the MRO,
7 and if the method called is the same as the current one, the arguments
8 passed to super() are the same as the parameters that were passed to
9 this method, then the method could be removed altogether, by letting
10 other implementation to take precedence.
11 """
12 if not _is_trivial_super_delegation(function):
13 return
14
15 call: nodes.Call = function.body[0].value
16
17 # Classes that override __eq__ should also override
18 # __hash__, even a trivial override is meaningful
19 if function.name == "__hash__":
20 for other_method in function.parent.mymethods():
21 if other_method.name == "__eq__":
22 return
23
24 # Check values of default args
25 klass = function.parent.frame(future=True)
26 meth_node = None
27 for overridden in klass.local_attr_ancestors(function.name):
28 # get astroid for the searched method
29 try:
30 meth_node = overridden[function.name]
31 except KeyError:
32 # we have found the method but it's not in the local
33 # dictionary.
34 # This may happen with astroid build from living objects
35 continue
36 if (
37 not isinstance(meth_node, nodes.FunctionDef)
38 # If the method have an ancestor which is not a
39 # function then it is legitimate to redefine it
40 or _has_different_parameters_default_value(
41 meth_node.args, function.args
42 )
43 # arguments to builtins such as Exception.__init__() cannot be inspected
44 or (meth_node.args.args is None and function.argnames() != ["self"])
45 ):
46 return
47 break
48
49 # Detect if the parameters are the same as the call's arguments.
50 params = _signature_from_arguments(function.args)
51 args = _signature_from_call(call)
52
53 if meth_node is not None:
54 # Detect if the super method uses varargs and the function doesn't or makes some of those explicit
55 if meth_node.args.vararg and (
56 not function.args.vararg
57 or len(function.args.args) > len(meth_node.args.args)
58 ):
59 return
60
61 def form_annotations(arguments: nodes.Arguments) -> list[str]:
62 annotations = chain(
63 (arguments.posonlyargs_annotations or []), arguments.annotations
64 )
65 return [ann.as_string() for ann in annotations if ann is not None]
66
67 called_annotations = form_annotations(function.args)
68 overridden_annotations = form_annotations(meth_node.args)
69 if called_annotations and overridden_annotations:
70 if called_annotations != overridden_annotations:
71 return
72
73 if (
74 function.returns is not None
75 and meth_node.returns is not None
76 and meth_node.returns.as_string() != function.returns.as_string()
77 ):
78 # Override adds typing information to the return type
79 return
80
81 if _definition_equivalent_to_call(params, args):
82 self.add_message(
83 "useless-parent-delegation",
84 node=function,
85 args=(function.name,),
86 confidence=INFERENCE,
87 )
Path 9: 2 calls (0.0)
FunctionDef (2)
None (2)
1def _check_useless_super_delegation(self, function: nodes.FunctionDef) -> None:
2 """Check if the given function node is an useless method override.
3
4 We consider it *useless* if it uses the super() builtin, but having
5 nothing additional whatsoever than not implementing the method at all.
6 If the method uses super() to delegate an operation to the rest of the MRO,
7 and if the method called is the same as the current one, the arguments
8 passed to super() are the same as the parameters that were passed to
9 this method, then the method could be removed altogether, by letting
10 other implementation to take precedence.
11 """
12 if not _is_trivial_super_delegation(function):
13 return
14
15 call: nodes.Call = function.body[0].value
16
17 # Classes that override __eq__ should also override
18 # __hash__, even a trivial override is meaningful
19 if function.name == "__hash__":
20 for other_method in function.parent.mymethods():
21 if other_method.name == "__eq__":
22 return
23
24 # Check values of default args
25 klass = function.parent.frame(future=True)
26 meth_node = None
27 for overridden in klass.local_attr_ancestors(function.name):
28 # get astroid for the searched method
29 try:
30 meth_node = overridden[function.name]
31 except KeyError:
32 # we have found the method but it's not in the local
33 # dictionary.
34 # This may happen with astroid build from living objects
35 continue
36 if (
37 not isinstance(meth_node, nodes.FunctionDef)
38 # If the method have an ancestor which is not a
39 # function then it is legitimate to redefine it
40 or _has_different_parameters_default_value(
41 meth_node.args, function.args
42 )
43 # arguments to builtins such as Exception.__init__() cannot be inspected
44 or (meth_node.args.args is None and function.argnames() != ["self"])
45 ):
46 return
47 break
48
49 # Detect if the parameters are the same as the call's arguments.
50 params = _signature_from_arguments(function.args)
51 args = _signature_from_call(call)
52
53 if meth_node is not None:
54 # Detect if the super method uses varargs and the function doesn't or makes some of those explicit
55 if meth_node.args.vararg and (
56 not function.args.vararg
57 or len(function.args.args) > len(meth_node.args.args)
58 ):
59 return
60
61 def form_annotations(arguments: nodes.Arguments) -> list[str]:
62 annotations = chain(
63 (arguments.posonlyargs_annotations or []), arguments.annotations
64 )
65 return [ann.as_string() for ann in annotations if ann is not None]
66
67 called_annotations = form_annotations(function.args)
68 overridden_annotations = form_annotations(meth_node.args)
69 if called_annotations and overridden_annotations:
70 if called_annotations != overridden_annotations:
71 return
72
73 if (
74 function.returns is not None
75 and meth_node.returns is not None
76 and meth_node.returns.as_string() != function.returns.as_string()
77 ):
78 # Override adds typing information to the return type
79 return
80
81 if _definition_equivalent_to_call(params, args):
82 self.add_message(
83 "useless-parent-delegation",
84 node=function,
85 args=(function.name,),
86 confidence=INFERENCE,
87 )
Path 10: 2 calls (0.0)
FunctionDef (2)
1def _check_useless_super_delegation(self, function: nodes.FunctionDef) -> None:
2 """Check if the given function node is an useless method override.
3
4 We consider it *useless* if it uses the super() builtin, but having
5 nothing additional whatsoever than not implementing the method at all.
6 If the method uses super() to delegate an operation to the rest of the MRO,
7 and if the method called is the same as the current one, the arguments
8 passed to super() are the same as the parameters that were passed to
9 this method, then the method could be removed altogether, by letting
10 other implementation to take precedence.
11 """
12 if not _is_trivial_super_delegation(function):
13 return
14
15 call: nodes.Call = function.body[0].value
16
17 # Classes that override __eq__ should also override
18 # __hash__, even a trivial override is meaningful
19 if function.name == "__hash__":
20 for other_method in function.parent.mymethods():
21 if other_method.name == "__eq__":
22 return
23
24 # Check values of default args
25 klass = function.parent.frame(future=True)
26 meth_node = None
27 for overridden in klass.local_attr_ancestors(function.name):
28 # get astroid for the searched method
29 try:
30 meth_node = overridden[function.name]
31 except KeyError:
32 # we have found the method but it's not in the local
33 # dictionary.
34 # This may happen with astroid build from living objects
35 continue
36 if (
37 not isinstance(meth_node, nodes.FunctionDef)
38 # If the method have an ancestor which is not a
39 # function then it is legitimate to redefine it
40 or _has_different_parameters_default_value(
41 meth_node.args, function.args
42 )
43 # arguments to builtins such as Exception.__init__() cannot be inspected
44 or (meth_node.args.args is None and function.argnames() != ["self"])
45 ):
46 return
47 break
48
49 # Detect if the parameters are the same as the call's arguments.
50 params = _signature_from_arguments(function.args)
51 args = _signature_from_call(call)
52
53 if meth_node is not None:
54 # Detect if the super method uses varargs and the function doesn't or makes some of those explicit
55 if meth_node.args.vararg and (
56 not function.args.vararg
57 or len(function.args.args) > len(meth_node.args.args)
58 ):
59 return
60
61 def form_annotations(arguments: nodes.Arguments) -> list[str]:
62 annotations = chain(
63 (arguments.posonlyargs_annotations or []), arguments.annotations
64 )
65 return [ann.as_string() for ann in annotations if ann is not None]
66
67 called_annotations = form_annotations(function.args)
68 overridden_annotations = form_annotations(meth_node.args)
69 if called_annotations and overridden_annotations:
70 if called_annotations != overridden_annotations:
71 return
72
73 if (
74 function.returns is not None
75 and meth_node.returns is not None
76 and meth_node.returns.as_string() != function.returns.as_string()
77 ):
78 # Override adds typing information to the return type
79 return
80
81 if _definition_equivalent_to_call(params, args):
82 self.add_message(
83 "useless-parent-delegation",
84 node=function,
85 args=(function.name,),
86 confidence=INFERENCE,
87 )
Path 11: 1 calls (0.0)
FunctionDef (1)
None (1)
1def _check_useless_super_delegation(self, function: nodes.FunctionDef) -> None:
2 """Check if the given function node is an useless method override.
3
4 We consider it *useless* if it uses the super() builtin, but having
5 nothing additional whatsoever than not implementing the method at all.
6 If the method uses super() to delegate an operation to the rest of the MRO,
7 and if the method called is the same as the current one, the arguments
8 passed to super() are the same as the parameters that were passed to
9 this method, then the method could be removed altogether, by letting
10 other implementation to take precedence.
11 """
12 if not _is_trivial_super_delegation(function):
13 return
14
15 call: nodes.Call = function.body[0].value
16
17 # Classes that override __eq__ should also override
18 # __hash__, even a trivial override is meaningful
19 if function.name == "__hash__":
20 for other_method in function.parent.mymethods():
21 if other_method.name == "__eq__":
22 return
23
24 # Check values of default args
25 klass = function.parent.frame(future=True)
26 meth_node = None
27 for overridden in klass.local_attr_ancestors(function.name):
28 # get astroid for the searched method
29 try:
30 meth_node = overridden[function.name]
31 except KeyError:
32 # we have found the method but it's not in the local
33 # dictionary.
34 # This may happen with astroid build from living objects
35 continue
36 if (
37 not isinstance(meth_node, nodes.FunctionDef)
38 # If the method have an ancestor which is not a
39 # function then it is legitimate to redefine it
40 or _has_different_parameters_default_value(
41 meth_node.args, function.args
42 )
43 # arguments to builtins such as Exception.__init__() cannot be inspected
44 or (meth_node.args.args is None and function.argnames() != ["self"])
45 ):
46 return
47 break
48
49 # Detect if the parameters are the same as the call's arguments.
50 params = _signature_from_arguments(function.args)
51 args = _signature_from_call(call)
52
53 if meth_node is not None:
54 # Detect if the super method uses varargs and the function doesn't or makes some of those explicit
55 if meth_node.args.vararg and (
56 not function.args.vararg
57 or len(function.args.args) > len(meth_node.args.args)
58 ):
59 return
60
61 def form_annotations(arguments: nodes.Arguments) -> list[str]:
62 annotations = chain(
63 (arguments.posonlyargs_annotations or []), arguments.annotations
64 )
65 return [ann.as_string() for ann in annotations if ann is not None]
66
67 called_annotations = form_annotations(function.args)
68 overridden_annotations = form_annotations(meth_node.args)
69 if called_annotations and overridden_annotations:
70 if called_annotations != overridden_annotations:
71 return
72
73 if (
74 function.returns is not None
75 and meth_node.returns is not None
76 and meth_node.returns.as_string() != function.returns.as_string()
77 ):
78 # Override adds typing information to the return type
79 return
80
81 if _definition_equivalent_to_call(params, args):
82 self.add_message(
83 "useless-parent-delegation",
84 node=function,
85 args=(function.name,),
86 confidence=INFERENCE,
87 )
Path 12: 1 calls (0.0)
FunctionDef (1)
None (1)
1def _check_useless_super_delegation(self, function: nodes.FunctionDef) -> None:
2 """Check if the given function node is an useless method override.
3
4 We consider it *useless* if it uses the super() builtin, but having
5 nothing additional whatsoever than not implementing the method at all.
6 If the method uses super() to delegate an operation to the rest of the MRO,
7 and if the method called is the same as the current one, the arguments
8 passed to super() are the same as the parameters that were passed to
9 this method, then the method could be removed altogether, by letting
10 other implementation to take precedence.
11 """
12 if not _is_trivial_super_delegation(function):
13 return
14
15 call: nodes.Call = function.body[0].value
16
17 # Classes that override __eq__ should also override
18 # __hash__, even a trivial override is meaningful
19 if function.name == "__hash__":
20 for other_method in function.parent.mymethods():
21 if other_method.name == "__eq__":
22 return
23
24 # Check values of default args
25 klass = function.parent.frame(future=True)
26 meth_node = None
27 for overridden in klass.local_attr_ancestors(function.name):
28 # get astroid for the searched method
29 try:
30 meth_node = overridden[function.name]
31 except KeyError:
32 # we have found the method but it's not in the local
33 # dictionary.
34 # This may happen with astroid build from living objects
35 continue
36 if (
37 not isinstance(meth_node, nodes.FunctionDef)
38 # If the method have an ancestor which is not a
39 # function then it is legitimate to redefine it
40 or _has_different_parameters_default_value(
41 meth_node.args, function.args
42 )
43 # arguments to builtins such as Exception.__init__() cannot be inspected
44 or (meth_node.args.args is None and function.argnames() != ["self"])
45 ):
46 return
47 break
48
49 # Detect if the parameters are the same as the call's arguments.
50 params = _signature_from_arguments(function.args)
51 args = _signature_from_call(call)
52
53 if meth_node is not None:
54 # Detect if the super method uses varargs and the function doesn't or makes some of those explicit
55 if meth_node.args.vararg and (
56 not function.args.vararg
57 or len(function.args.args) > len(meth_node.args.args)
58 ):
59 return
60
61 def form_annotations(arguments: nodes.Arguments) -> list[str]:
62 annotations = chain(
63 (arguments.posonlyargs_annotations or []), arguments.annotations
64 )
65 return [ann.as_string() for ann in annotations if ann is not None]
66
67 called_annotations = form_annotations(function.args)
68 overridden_annotations = form_annotations(meth_node.args)
69 if called_annotations and overridden_annotations:
70 if called_annotations != overridden_annotations:
71 return
72
73 if (
74 function.returns is not None
75 and meth_node.returns is not None
76 and meth_node.returns.as_string() != function.returns.as_string()
77 ):
78 # Override adds typing information to the return type
79 return
80
81 if _definition_equivalent_to_call(params, args):
82 self.add_message(
83 "useless-parent-delegation",
84 node=function,
85 args=(function.name,),
86 confidence=INFERENCE,
87 )
Path 13: 1 calls (0.0)
FunctionDef (1)
1def _check_useless_super_delegation(self, function: nodes.FunctionDef) -> None:
2 """Check if the given function node is an useless method override.
3
4 We consider it *useless* if it uses the super() builtin, but having
5 nothing additional whatsoever than not implementing the method at all.
6 If the method uses super() to delegate an operation to the rest of the MRO,
7 and if the method called is the same as the current one, the arguments
8 passed to super() are the same as the parameters that were passed to
9 this method, then the method could be removed altogether, by letting
10 other implementation to take precedence.
11 """
12 if not _is_trivial_super_delegation(function):
13 return
14
15 call: nodes.Call = function.body[0].value
16
17 # Classes that override __eq__ should also override
18 # __hash__, even a trivial override is meaningful
19 if function.name == "__hash__":
20 for other_method in function.parent.mymethods():
21 if other_method.name == "__eq__":
22 return
23
24 # Check values of default args
25 klass = function.parent.frame(future=True)
26 meth_node = None
27 for overridden in klass.local_attr_ancestors(function.name):
28 # get astroid for the searched method
29 try:
30 meth_node = overridden[function.name]
31 except KeyError:
32 # we have found the method but it's not in the local
33 # dictionary.
34 # This may happen with astroid build from living objects
35 continue
36 if (
37 not isinstance(meth_node, nodes.FunctionDef)
38 # If the method have an ancestor which is not a
39 # function then it is legitimate to redefine it
40 or _has_different_parameters_default_value(
41 meth_node.args, function.args
42 )
43 # arguments to builtins such as Exception.__init__() cannot be inspected
44 or (meth_node.args.args is None and function.argnames() != ["self"])
45 ):
46 return
47 break
48
49 # Detect if the parameters are the same as the call's arguments.
50 params = _signature_from_arguments(function.args)
51 args = _signature_from_call(call)
52
53 if meth_node is not None:
54 # Detect if the super method uses varargs and the function doesn't or makes some of those explicit
55 if meth_node.args.vararg and (
56 not function.args.vararg
57 or len(function.args.args) > len(meth_node.args.args)
58 ):
59 return
60
61 def form_annotations(arguments: nodes.Arguments) -> list[str]:
62 annotations = chain(
63 (arguments.posonlyargs_annotations or []), arguments.annotations
64 )
65 return [ann.as_string() for ann in annotations if ann is not None]
66
67 called_annotations = form_annotations(function.args)
68 overridden_annotations = form_annotations(meth_node.args)
69 if called_annotations and overridden_annotations:
70 if called_annotations != overridden_annotations:
71 return
72
73 if (
74 function.returns is not None
75 and meth_node.returns is not None
76 and meth_node.returns.as_string() != function.returns.as_string()
77 ):
78 # Override adds typing information to the return type
79 return
80
81 if _definition_equivalent_to_call(params, args):
82 self.add_message(
83 "useless-parent-delegation",
84 node=function,
85 args=(function.name,),
86 confidence=INFERENCE,
87 )
Path 14: 1 calls (0.0)
FunctionDef (1)
None (1)
1def _check_useless_super_delegation(self, function: nodes.FunctionDef) -> None:
2 """Check if the given function node is an useless method override.
3
4 We consider it *useless* if it uses the super() builtin, but having
5 nothing additional whatsoever than not implementing the method at all.
6 If the method uses super() to delegate an operation to the rest of the MRO,
7 and if the method called is the same as the current one, the arguments
8 passed to super() are the same as the parameters that were passed to
9 this method, then the method could be removed altogether, by letting
10 other implementation to take precedence.
11 """
12 if not _is_trivial_super_delegation(function):
13 return
14
15 call: nodes.Call = function.body[0].value
16
17 # Classes that override __eq__ should also override
18 # __hash__, even a trivial override is meaningful
19 if function.name == "__hash__":
20 for other_method in function.parent.mymethods():
21 if other_method.name == "__eq__":
22 return
23
24 # Check values of default args
25 klass = function.parent.frame(future=True)
26 meth_node = None
27 for overridden in klass.local_attr_ancestors(function.name):
28 # get astroid for the searched method
29 try:
30 meth_node = overridden[function.name]
31 except KeyError:
32 # we have found the method but it's not in the local
33 # dictionary.
34 # This may happen with astroid build from living objects
35 continue
36 if (
37 not isinstance(meth_node, nodes.FunctionDef)
38 # If the method have an ancestor which is not a
39 # function then it is legitimate to redefine it
40 or _has_different_parameters_default_value(
41 meth_node.args, function.args
42 )
43 # arguments to builtins such as Exception.__init__() cannot be inspected
44 or (meth_node.args.args is None and function.argnames() != ["self"])
45 ):
46 return
47 break
48
49 # Detect if the parameters are the same as the call's arguments.
50 params = _signature_from_arguments(function.args)
51 args = _signature_from_call(call)
52
53 if meth_node is not None:
54 # Detect if the super method uses varargs and the function doesn't or makes some of those explicit
55 if meth_node.args.vararg and (
56 not function.args.vararg
57 or len(function.args.args) > len(meth_node.args.args)
58 ):
59 return
60
61 def form_annotations(arguments: nodes.Arguments) -> list[str]:
62 annotations = chain(
63 (arguments.posonlyargs_annotations or []), arguments.annotations
64 )
65 return [ann.as_string() for ann in annotations if ann is not None]
66
67 called_annotations = form_annotations(function.args)
68 overridden_annotations = form_annotations(meth_node.args)
69 if called_annotations and overridden_annotations:
70 if called_annotations != overridden_annotations:
71 return
72
73 if (
74 function.returns is not None
75 and meth_node.returns is not None
76 and meth_node.returns.as_string() != function.returns.as_string()
77 ):
78 # Override adds typing information to the return type
79 return
80
81 if _definition_equivalent_to_call(params, args):
82 self.add_message(
83 "useless-parent-delegation",
84 node=function,
85 args=(function.name,),
86 confidence=INFERENCE,
87 )
Path 15: 1 calls (0.0)
FunctionDef (1)
1def _check_useless_super_delegation(self, function: nodes.FunctionDef) -> None:
2 """Check if the given function node is an useless method override.
3
4 We consider it *useless* if it uses the super() builtin, but having
5 nothing additional whatsoever than not implementing the method at all.
6 If the method uses super() to delegate an operation to the rest of the MRO,
7 and if the method called is the same as the current one, the arguments
8 passed to super() are the same as the parameters that were passed to
9 this method, then the method could be removed altogether, by letting
10 other implementation to take precedence.
11 """
12 if not _is_trivial_super_delegation(function):
13 return
14
15 call: nodes.Call = function.body[0].value
16
17 # Classes that override __eq__ should also override
18 # __hash__, even a trivial override is meaningful
19 if function.name == "__hash__":
20 for other_method in function.parent.mymethods():
21 if other_method.name == "__eq__":
22 return
23
24 # Check values of default args
25 klass = function.parent.frame(future=True)
26 meth_node = None
27 for overridden in klass.local_attr_ancestors(function.name):
28 # get astroid for the searched method
29 try:
30 meth_node = overridden[function.name]
31 except KeyError:
32 # we have found the method but it's not in the local
33 # dictionary.
34 # This may happen with astroid build from living objects
35 continue
36 if (
37 not isinstance(meth_node, nodes.FunctionDef)
38 # If the method have an ancestor which is not a
39 # function then it is legitimate to redefine it
40 or _has_different_parameters_default_value(
41 meth_node.args, function.args
42 )
43 # arguments to builtins such as Exception.__init__() cannot be inspected
44 or (meth_node.args.args is None and function.argnames() != ["self"])
45 ):
46 return
47 break
48
49 # Detect if the parameters are the same as the call's arguments.
50 params = _signature_from_arguments(function.args)
51 args = _signature_from_call(call)
52
53 if meth_node is not None:
54 # Detect if the super method uses varargs and the function doesn't or makes some of those explicit
55 if meth_node.args.vararg and (
56 not function.args.vararg
57 or len(function.args.args) > len(meth_node.args.args)
58 ):
59 return
60
61 def form_annotations(arguments: nodes.Arguments) -> list[str]:
62 annotations = chain(
63 (arguments.posonlyargs_annotations or []), arguments.annotations
64 )
65 return [ann.as_string() for ann in annotations if ann is not None]
66
67 called_annotations = form_annotations(function.args)
68 overridden_annotations = form_annotations(meth_node.args)
69 if called_annotations and overridden_annotations:
70 if called_annotations != overridden_annotations:
71 return
72
73 if (
74 function.returns is not None
75 and meth_node.returns is not None
76 and meth_node.returns.as_string() != function.returns.as_string()
77 ):
78 # Override adds typing information to the return type
79 return
80
81 if _definition_equivalent_to_call(params, args):
82 self.add_message(
83 "useless-parent-delegation",
84 node=function,
85 args=(function.name,),
86 confidence=INFERENCE,
87 )
Path 16: 1 calls (0.0)
FunctionDef (1)
None (1)
1def _check_useless_super_delegation(self, function: nodes.FunctionDef) -> None:
2 """Check if the given function node is an useless method override.
3
4 We consider it *useless* if it uses the super() builtin, but having
5 nothing additional whatsoever than not implementing the method at all.
6 If the method uses super() to delegate an operation to the rest of the MRO,
7 and if the method called is the same as the current one, the arguments
8 passed to super() are the same as the parameters that were passed to
9 this method, then the method could be removed altogether, by letting
10 other implementation to take precedence.
11 """
12 if not _is_trivial_super_delegation(function):
13 return
14
15 call: nodes.Call = function.body[0].value
16
17 # Classes that override __eq__ should also override
18 # __hash__, even a trivial override is meaningful
19 if function.name == "__hash__":
20 for other_method in function.parent.mymethods():
21 if other_method.name == "__eq__":
22 return
23
24 # Check values of default args
25 klass = function.parent.frame(future=True)
26 meth_node = None
27 for overridden in klass.local_attr_ancestors(function.name):
28 # get astroid for the searched method
29 try:
30 meth_node = overridden[function.name]
31 except KeyError:
32 # we have found the method but it's not in the local
33 # dictionary.
34 # This may happen with astroid build from living objects
35 continue
36 if (
37 not isinstance(meth_node, nodes.FunctionDef)
38 # If the method have an ancestor which is not a
39 # function then it is legitimate to redefine it
40 or _has_different_parameters_default_value(
41 meth_node.args, function.args
42 )
43 # arguments to builtins such as Exception.__init__() cannot be inspected
44 or (meth_node.args.args is None and function.argnames() != ["self"])
45 ):
46 return
47 break
48
49 # Detect if the parameters are the same as the call's arguments.
50 params = _signature_from_arguments(function.args)
51 args = _signature_from_call(call)
52
53 if meth_node is not None:
54 # Detect if the super method uses varargs and the function doesn't or makes some of those explicit
55 if meth_node.args.vararg and (
56 not function.args.vararg
57 or len(function.args.args) > len(meth_node.args.args)
58 ):
59 return
60
61 def form_annotations(arguments: nodes.Arguments) -> list[str]:
62 annotations = chain(
63 (arguments.posonlyargs_annotations or []), arguments.annotations
64 )
65 return [ann.as_string() for ann in annotations if ann is not None]
66
67 called_annotations = form_annotations(function.args)
68 overridden_annotations = form_annotations(meth_node.args)
69 if called_annotations and overridden_annotations:
70 if called_annotations != overridden_annotations:
71 return
72
73 if (
74 function.returns is not None
75 and meth_node.returns is not None
76 and meth_node.returns.as_string() != function.returns.as_string()
77 ):
78 # Override adds typing information to the return type
79 return
80
81 if _definition_equivalent_to_call(params, args):
82 self.add_message(
83 "useless-parent-delegation",
84 node=function,
85 args=(function.name,),
86 confidence=INFERENCE,
87 )
Path 17: 1 calls (0.0)
FunctionDef (1)
1def _check_useless_super_delegation(self, function: nodes.FunctionDef) -> None:
2 """Check if the given function node is an useless method override.
3
4 We consider it *useless* if it uses the super() builtin, but having
5 nothing additional whatsoever than not implementing the method at all.
6 If the method uses super() to delegate an operation to the rest of the MRO,
7 and if the method called is the same as the current one, the arguments
8 passed to super() are the same as the parameters that were passed to
9 this method, then the method could be removed altogether, by letting
10 other implementation to take precedence.
11 """
12 if not _is_trivial_super_delegation(function):
13 return
14
15 call: nodes.Call = function.body[0].value
16
17 # Classes that override __eq__ should also override
18 # __hash__, even a trivial override is meaningful
19 if function.name == "__hash__":
20 for other_method in function.parent.mymethods():
21 if other_method.name == "__eq__":
22 return
23
24 # Check values of default args
25 klass = function.parent.frame(future=True)
26 meth_node = None
27 for overridden in klass.local_attr_ancestors(function.name):
28 # get astroid for the searched method
29 try:
30 meth_node = overridden[function.name]
31 except KeyError:
32 # we have found the method but it's not in the local
33 # dictionary.
34 # This may happen with astroid build from living objects
35 continue
36 if (
37 not isinstance(meth_node, nodes.FunctionDef)
38 # If the method have an ancestor which is not a
39 # function then it is legitimate to redefine it
40 or _has_different_parameters_default_value(
41 meth_node.args, function.args
42 )
43 # arguments to builtins such as Exception.__init__() cannot be inspected
44 or (meth_node.args.args is None and function.argnames() != ["self"])
45 ):
46 return
47 break
48
49 # Detect if the parameters are the same as the call's arguments.
50 params = _signature_from_arguments(function.args)
51 args = _signature_from_call(call)
52
53 if meth_node is not None:
54 # Detect if the super method uses varargs and the function doesn't or makes some of those explicit
55 if meth_node.args.vararg and (
56 not function.args.vararg
57 or len(function.args.args) > len(meth_node.args.args)
58 ):
59 return
60
61 def form_annotations(arguments: nodes.Arguments) -> list[str]:
62 annotations = chain(
63 (arguments.posonlyargs_annotations or []), arguments.annotations
64 )
65 return [ann.as_string() for ann in annotations if ann is not None]
66
67 called_annotations = form_annotations(function.args)
68 overridden_annotations = form_annotations(meth_node.args)
69 if called_annotations and overridden_annotations:
70 if called_annotations != overridden_annotations:
71 return
72
73 if (
74 function.returns is not None
75 and meth_node.returns is not None
76 and meth_node.returns.as_string() != function.returns.as_string()
77 ):
78 # Override adds typing information to the return type
79 return
80
81 if _definition_equivalent_to_call(params, args):
82 self.add_message(
83 "useless-parent-delegation",
84 node=function,
85 args=(function.name,),
86 confidence=INFERENCE,
87 )
Path 18: 1 calls (0.0)
FunctionDef (1)
1def _check_useless_super_delegation(self, function: nodes.FunctionDef) -> None:
2 """Check if the given function node is an useless method override.
3
4 We consider it *useless* if it uses the super() builtin, but having
5 nothing additional whatsoever than not implementing the method at all.
6 If the method uses super() to delegate an operation to the rest of the MRO,
7 and if the method called is the same as the current one, the arguments
8 passed to super() are the same as the parameters that were passed to
9 this method, then the method could be removed altogether, by letting
10 other implementation to take precedence.
11 """
12 if not _is_trivial_super_delegation(function):
13 return
14
15 call: nodes.Call = function.body[0].value
16
17 # Classes that override __eq__ should also override
18 # __hash__, even a trivial override is meaningful
19 if function.name == "__hash__":
20 for other_method in function.parent.mymethods():
21 if other_method.name == "__eq__":
22 return
23
24 # Check values of default args
25 klass = function.parent.frame(future=True)
26 meth_node = None
27 for overridden in klass.local_attr_ancestors(function.name):
28 # get astroid for the searched method
29 try:
30 meth_node = overridden[function.name]
31 except KeyError:
32 # we have found the method but it's not in the local
33 # dictionary.
34 # This may happen with astroid build from living objects
35 continue
36 if (
37 not isinstance(meth_node, nodes.FunctionDef)
38 # If the method have an ancestor which is not a
39 # function then it is legitimate to redefine it
40 or _has_different_parameters_default_value(
41 meth_node.args, function.args
42 )
43 # arguments to builtins such as Exception.__init__() cannot be inspected
44 or (meth_node.args.args is None and function.argnames() != ["self"])
45 ):
46 return
47 break
48
49 # Detect if the parameters are the same as the call's arguments.
50 params = _signature_from_arguments(function.args)
51 args = _signature_from_call(call)
52
53 if meth_node is not None:
54 # Detect if the super method uses varargs and the function doesn't or makes some of those explicit
55 if meth_node.args.vararg and (
56 not function.args.vararg
57 or len(function.args.args) > len(meth_node.args.args)
58 ):
59 return
60
61 def form_annotations(arguments: nodes.Arguments) -> list[str]:
62 annotations = chain(
63 (arguments.posonlyargs_annotations or []), arguments.annotations
64 )
65 return [ann.as_string() for ann in annotations if ann is not None]
66
67 called_annotations = form_annotations(function.args)
68 overridden_annotations = form_annotations(meth_node.args)
69 if called_annotations and overridden_annotations:
70 if called_annotations != overridden_annotations:
71 return
72
73 if (
74 function.returns is not None
75 and meth_node.returns is not None
76 and meth_node.returns.as_string() != function.returns.as_string()
77 ):
78 # Override adds typing information to the return type
79 return
80
81 if _definition_equivalent_to_call(params, args):
82 self.add_message(
83 "useless-parent-delegation",
84 node=function,
85 args=(function.name,),
86 confidence=INFERENCE,
87 )