diff --git a/doc/whatsnew/fragments/8919.false_positive b/doc/whatsnew/fragments/8919.false_positive new file mode 100644 index 00000000000..2e5972f3dfe --- /dev/null +++ b/doc/whatsnew/fragments/8919.false_positive @@ -0,0 +1,3 @@ +Fix false positive for ``arguments-differ`` when overriding `__init_subclass__`. + +Closes #8919 diff --git a/pylint/checkers/classes/class_checker.py b/pylint/checkers/classes/class_checker.py index ff93ac07ce2..c2ec70acfaf 100644 --- a/pylint/checkers/classes/class_checker.py +++ b/pylint/checkers/classes/class_checker.py @@ -370,14 +370,6 @@ def _different_parameters( if different_kwonly: output_messages += different_kwonly - if original.name in PYMETHODS: - # Ignore the difference for special methods. If the parameter - # numbers are different, then that is going to be caught by - # unexpected-special-method-signature. - # If the names are different, it doesn't matter, since they can't - # be used as keyword arguments anyway. - output_messages.clear() - # Arguments will only violate LSP if there are variadics in the original # that are then removed from the overridden kwarg_lost = original.args.kwarg and not overridden.args.kwarg @@ -386,6 +378,14 @@ def _different_parameters( if kwarg_lost or vararg_lost: output_messages += ["Variadics removed in"] + if original.name in PYMETHODS: + # Ignore the difference for special methods. If the parameter + # numbers are different, then that is going to be caught by + # unexpected-special-method-signature. + # If the names are different, it doesn't matter, since they can't + # be used as keyword arguments anyway. + output_messages.clear() + return output_messages diff --git a/tests/functional/a/arguments_differ.py b/tests/functional/a/arguments_differ.py index 65e953d769a..1c56ecc0834 100644 --- a/tests/functional/a/arguments_differ.py +++ b/tests/functional/a/arguments_differ.py @@ -358,3 +358,13 @@ def method(self, *, arg1): class ClassWithNewNonDefaultKeywordOnly(AClass): def method(self, *, arg2, arg1=None): # [arguments-differ] ... + + +# Exclude `__init_subclass__` from the check: +class InitSubclassParent: + def __init_subclass__(cls, *args, **kwargs): + ... + +class InitSubclassChild(InitSubclassParent): + def __init_subclass__(cls, /, **kwargs) -> None: + super().__init_subclass__(**kwargs)