diff --git a/doc/whatsnew/fragments/10208.false_positive b/doc/whatsnew/fragments/10208.false_positive new file mode 100644 index 0000000000..b2ab63045f --- /dev/null +++ b/doc/whatsnew/fragments/10208.false_positive @@ -0,0 +1,3 @@ +Fix a false positive for ``invalid-getnewargs-ex-returned`` when the tuple or dict has been assigned to a name. + +Closes #10208 diff --git a/pylint/checkers/classes/special_methods_checker.py b/pylint/checkers/classes/special_methods_checker.py index 025f285622..e1e19346dc 100644 --- a/pylint/checkers/classes/special_methods_checker.py +++ b/pylint/checkers/classes/special_methods_checker.py @@ -391,7 +391,7 @@ def _check_getnewargs_ex( (inferred.elts[0], self._is_tuple), (inferred.elts[1], self._is_dict), ): - if isinstance(arg, nodes.Call): + if isinstance(arg, (nodes.Call, nodes.Name)): arg = safe_infer(arg) if arg and not isinstance(arg, util.UninferableBase): diff --git a/tests/functional/i/invalid/invalid_getnewargs/invalid_getnewargs_ex_returned.py b/tests/functional/i/invalid/invalid_getnewargs/invalid_getnewargs_ex_returned.py index efe6ba25fb..bb773b75bd 100644 --- a/tests/functional/i/invalid/invalid_getnewargs/invalid_getnewargs_ex_returned.py +++ b/tests/functional/i/invalid/invalid_getnewargs/invalid_getnewargs_ex_returned.py @@ -30,6 +30,24 @@ class ThirdGoodGetNewArgsEx: """GetNewArgsEx through the metaclass.""" +class FourthGoodGetNewArgsEx: + """Test that `args` and `kwargs` (`Name` nodes) are inferred as tuples. + + https://github.com/pylint-dev/pylint/issues/10208 + """ + def __init__(self, boo, far, *, hoo, haha): + self._foo = boo + self._bar = far + self._hoo = hoo + self._haha = haha + + def __getnewargs_ex__(self): + args = (self._foo, self._bar) + kwargs = {'hoo': self._hoo, + 'haha': self._haha} + return args, kwargs + + class FirstBadGetNewArgsEx: """ __getnewargs_ex__ returns an integer """ diff --git a/tests/functional/i/invalid/invalid_getnewargs/invalid_getnewargs_ex_returned.txt b/tests/functional/i/invalid/invalid_getnewargs/invalid_getnewargs_ex_returned.txt index b657c5f40b..f20a283621 100644 --- a/tests/functional/i/invalid/invalid_getnewargs/invalid_getnewargs_ex_returned.txt +++ b/tests/functional/i/invalid/invalid_getnewargs/invalid_getnewargs_ex_returned.txt @@ -1,6 +1,6 @@ -invalid-getnewargs-ex-returned:36:4:36:25:FirstBadGetNewArgsEx.__getnewargs_ex__:__getnewargs_ex__ does not return a tuple containing (tuple, dict):UNDEFINED -invalid-getnewargs-ex-returned:43:4:43:25:SecondBadGetNewArgsEx.__getnewargs_ex__:__getnewargs_ex__ does not return a tuple containing (tuple, dict):UNDEFINED -invalid-getnewargs-ex-returned:50:4:50:25:ThirdBadGetNewArgsEx.__getnewargs_ex__:__getnewargs_ex__ does not return a tuple containing (tuple, dict):UNDEFINED -invalid-getnewargs-ex-returned:57:4:57:25:FourthBadGetNewArgsEx.__getnewargs_ex__:__getnewargs_ex__ does not return a tuple containing (tuple, dict):UNDEFINED -invalid-getnewargs-ex-returned:64:4:64:25:FifthBadGetNewArgsEx.__getnewargs_ex__:__getnewargs_ex__ does not return a tuple containing (tuple, dict):UNDEFINED -invalid-getnewargs-ex-returned:71:4:71:25:SixthBadGetNewArgsEx.__getnewargs_ex__:__getnewargs_ex__ does not return a tuple containing (tuple, dict):UNDEFINED +invalid-getnewargs-ex-returned:54:4:54:25:FirstBadGetNewArgsEx.__getnewargs_ex__:__getnewargs_ex__ does not return a tuple containing (tuple, dict):UNDEFINED +invalid-getnewargs-ex-returned:61:4:61:25:SecondBadGetNewArgsEx.__getnewargs_ex__:__getnewargs_ex__ does not return a tuple containing (tuple, dict):UNDEFINED +invalid-getnewargs-ex-returned:68:4:68:25:ThirdBadGetNewArgsEx.__getnewargs_ex__:__getnewargs_ex__ does not return a tuple containing (tuple, dict):UNDEFINED +invalid-getnewargs-ex-returned:75:4:75:25:FourthBadGetNewArgsEx.__getnewargs_ex__:__getnewargs_ex__ does not return a tuple containing (tuple, dict):UNDEFINED +invalid-getnewargs-ex-returned:82:4:82:25:FifthBadGetNewArgsEx.__getnewargs_ex__:__getnewargs_ex__ does not return a tuple containing (tuple, dict):UNDEFINED +invalid-getnewargs-ex-returned:89:4:89:25:SixthBadGetNewArgsEx.__getnewargs_ex__:__getnewargs_ex__ does not return a tuple containing (tuple, dict):UNDEFINED