Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Suppress useless-super-delegation if return type changed (#5822) #6141

Merged
merged 4 commits into from Apr 15, 2022

Conversation

timmartin
Copy link
Contributor

Type of Changes

Type
βœ“ πŸ› Bug fix

Description

In the useless-super-delegation checker, check whether the return type annotation has been specialized in the derived class. If so, then the override is not useless and we should not issue the warning.

Closes #5822

@coveralls
Copy link

coveralls commented Apr 2, 2022

Pull Request Test Coverage Report for Build 2171288819

  • 2 of 2 (100.0%) changed or added relevant lines in 1 file are covered.
  • 13 unchanged lines in 1 file lost coverage.
  • Overall coverage increased (+0.003%) to 93.379%

Files with Coverage Reduction New Missed Lines %
pylint/lint/pylinter.py 13 95.89%
Totals Coverage Status
Change from base Build 2169544822: 0.003%
Covered Lines: 15979
Relevant Lines: 17112

πŸ’› - Coveralls

class ReturnTypeAny:
choices = ['a', 1, (2, 3)]

def draw(self) -> None:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This annotation is incorrect, is that intentional?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well spotted, that wasn't intentional.

While I was fixing that, I realized there's another case we need to think about:

import typing
from typing import Any

class Base:
    def foo(self) -> Any:
        pass

class Derived:
    def foo(self) -> typing.Any:
        return super().foo()

This will be harder to fix, and it looks like the existing rules around type hints on parameters don't cope with this case either, so I suggest this can be handled as a later fix to both parameter type hints and return type hint.

@Pierre-Sassoulas Pierre-Sassoulas added False Positive 🦟 A message is emitted but nothing is wrong with the code Needs backport Needs to be cherry-picked on the current patch version by a pylint's maintainer labels Apr 2, 2022
@Pierre-Sassoulas Pierre-Sassoulas added this to the 2.13.5 milestone Apr 2, 2022
Copy link
Member

@Pierre-Sassoulas Pierre-Sassoulas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@DanielNoord
Copy link
Collaborator

@cdce8p I'd like to get your input here. I'm not sure if this change is reasonable. We're not a type checker, but should we support this? You're probably the best person to judge this.

@DanielNoord DanielNoord removed their request for review April 3, 2022 20:08
@tushar-deepsource
Copy link
Contributor

I'd say this is a good change. It's a change that will lead to less false positives, and it's something that we can infer, so why not take advantage of it?

@Pierre-Sassoulas Pierre-Sassoulas modified the milestones: 2.13.5, 2.13.6 Apr 6, 2022
@Pierre-Sassoulas Pierre-Sassoulas mentioned this pull request Apr 11, 2022
4 tasks
@Pierre-Sassoulas
Copy link
Member

@cdce8p could you check this, if you have some time ? It's blocking the release of 2.13.6 :)

Copy link
Member

@cdce8p cdce8p left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not fully convinced it is all that useful, but I guess we can add it. Especially since we do something similar for the parameter annotations already.

Just two suggestions:

  • Do not return if one function doesn't have a return type (similar to parameter annotations).
  • Move it below the if called_annotations and overridden_annotations block.

pylint/checkers/classes/class_checker.py Outdated Show resolved Hide resolved
@timmartin
Copy link
Contributor Author

I'm not sure what you mean by "Do not return if one function doesn't have a return type (similar to parameter annotations)." Currently my reasoning is that if the derived method adds a type missing from the base method we should not warn useless-super-delegation, but if the base method has the annotation and the derived method doesn't then we should warn. Is that what you're meaning?

@cdce8p
Copy link
Member

cdce8p commented Apr 14, 2022

I'm not sure what you mean by "Do not return if one function doesn't have a return type (similar to parameter annotations)." Currently my reasoning is that if the derived method adds a type missing from the base method we should not warn useless-super-delegation, but if the base method has the annotation and the derived method doesn't then we should warn. Is that what you're meaning?

My idea was to be careful not to block too many errors. I.e. my suggestion would be to only ignore useless-super-delegation if both the parent and child method have function annotations and they differ.

Copy link
Member

@cdce8p cdce8p left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't force push changes new here. That will make it difficult / impossible to see and compare old revisions.

Comment on lines 1301 to 1305
if (
function.returns is not None
and meth_node.returns is None
or meth_node.returns.as_string() != function.returns.as_string()
):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (
function.returns is not None
and meth_node.returns is None
or meth_node.returns.as_string() != function.returns.as_string()
):
if function.returns is not None and (
meth_node.returns is None
or meth_node.returns.as_string() != function.returns.as_string()
):

To fix the tests, you would need to use the old condition.

For my #6141 (comment), I suggested something a little bit different.

Suggested change
if (
function.returns is not None
and meth_node.returns is None
or meth_node.returns.as_string() != function.returns.as_string()
):
if (
function.returns is not None
and meth_node.returns is not None
and meth_node.returns.as_string() != function.returns.as_string()
):

@timmartin
Copy link
Contributor Author

My thinking was that the most likely reason I could think to override a method just to change the return type annotation is that I was extending some library code that doesn't have type declarations and I wanted my library to have type declarations, in which case issuing a diagnostic isn't helpful. I'm not sure I care enough about this to prolong the discussion, though.

@cdce8p
Copy link
Member

cdce8p commented Apr 15, 2022

My thinking was that the most likely reason I could think to override a method just to change the return type annotation is that I was extending some library code that doesn't have type declarations and I wanted my library to have type declarations, in which case issuing a diagnostic isn't helpful. I'm not sure I care enough about this to prolong the discussion, though.

Usually, I think it would be better if the original library added type hints itself. However, I do agree that it's not worth the discussion. If you think it would be helpful, I guess we could do that, too. Will leave that up to you.

@timmartin
Copy link
Contributor Author

No, I'm done with this change. Merge it or close the PR as you see fit.

@Pierre-Sassoulas Pierre-Sassoulas merged commit 9b3314b into pylint-dev:main Apr 15, 2022
@Pierre-Sassoulas
Copy link
Member

Thank you for the fix @timmartin !

@Pierre-Sassoulas Pierre-Sassoulas added Backported and removed Needs backport Needs to be cherry-picked on the current patch version by a pylint's maintainer labels Apr 20, 2022
Pierre-Sassoulas pushed a commit that referenced this pull request Apr 20, 2022
…6141)

* Reinstate warning if base method has no return type annotation
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Backported False Positive 🦟 A message is emitted but nothing is wrong with the code
Projects
None yet
Development

Successfully merging this pull request may close these issues.

useless-super-delegation when an override changes the return type annotation
6 participants