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

Add more precise error message for Callable annotation #12518

Merged

Conversation

frerikandriessen
Copy link
Contributor

Description

Adds a more precise error message for a Callable annotation, if the
option --disallow-any-generics (part of --strict mode) has been used. The suggestion in the old
message was incorrect in this scenario.

Fixes #11757

Test Plan

Contents of test.py:

from typing import Callable

def my_function(callback: Callable[...]) -> None:
    callback()

Results:

$ mypy test.py --disallow-any-generics
test.py:3: error: Please use "Callable[[<parameters>], <return type>]" or "Callable[..., Any]"
Found 1 error in 1 file (checked 1 source file)
$ mypy test.py
test.py:3: error: Please use "Callable[[<parameters>], <return type>]" or "Callable"
Found 1 error in 1 file (checked 1 source file)

@JelleZijlstra
Copy link
Member

What if we just remove the "or Callable" part? We should nudge people towards more precise types, and error messages don't need to include every detail.

@AlexWaygood
Copy link
Member

AlexWaygood commented Apr 4, 2022

What if we just remove the "or Callable" part? We should nudge people towards more precise types, and error messages don't need to include every detail.

We could probably remove the "or Callable" part if a user has the --disallow-any-generics flag set to True. I don't think that would be a good idea if a user doesn't have that flag set, though. I think we should support gradual typing as much as possible, and Callable is one of the least ergonomic types when it comes to parameterization.

@frerikandriessen
Copy link
Contributor Author

One of my least favorite parts of typing is typing a Callable that has a very intricate call signature. Most of the times, the Callables that are very complex to type are Callables that I do not even directly use in my code but have to type to satisfy mypy. It's nice to, in those cases, be able to just use Callable[..., Any] to explicitly indicate the specific typing is not important.

That said, I can see an argument being made that, if you choose for the --strict flag, you want to only allow the strictest way. But then why allow the shorter form in this mode anyway?
With regards to nudging, I'd say that if you have --strict mode enabled (I'm assuming this is the case for most situations where --disallow-any-generics is enabled), you are already intent on doing the "right" thing; hiding this information would just make it more annoying to do so.

Dependent on the outcome of this discussion I will fix the flake8 error or change the error message.

@github-actions

This comment has been minimized.

@JelleZijlstra
Copy link
Member

@frerikandriessen what flake8 error are you referring to?

And note that I'm not proposing to remove the ability to write "Callable[..., Any]", just to make the error message more concise in this case.

@AlexWaygood
Copy link
Member

@frerikandriessen what flake8 error are you referring to?

The flake8 CI check is failing because one of the lines is slightly too long

mypy/typeanal.py Outdated
@@ -813,7 +813,10 @@ def analyze_callable_type(self, t: UnboundType) -> Type:
return AnyType(TypeOfAny.from_error)
ret = maybe_ret
else:
self.fail('Please use "Callable[[<parameters>], <return type>]" or "Callable"', t)
if self.options.disallow_any_generics:
self.fail('Please use "Callable[[<parameters>], <return type>]" or "Callable[..., Any]"', t)
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
self.fail('Please use "Callable[[<parameters>], <return type>]" or "Callable[..., Any]"', t)
self.fail('Please use "Callable[[<parameters>], <return type>]"', t)

Let's remove the suboptimal suggestion here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

My 2 cents: I actually want to keep the error message with both suggestions, because the 'suboptimal' suggestion is exactly what I wanted to know. So for me it was very helpful (albeit unfortunately misleading, which is why I've corrected it). Just to emphasize that some users will get value from the not-concise message.

That said, if you still want me to remove that part I'll gladly do so.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@JelleZijlstra just to double-check: I lined out above why I wanted to keep that message as is. Do you still want me to change it?

Copy link
Member

Choose a reason for hiding this comment

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

I'd still lean towards removing it. Error messages should be short and provide the most useful option, and Callable[..., Any] generally isn't what we should steer people towards.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Okay, I've incorporated your suggestion

Adds a more precise error message for a Callable annotation, if the
option --disallow-any-generics has been used. The suggestion in the old
message was incorrect in this scenario.
@frerikandriessen frerikandriessen force-pushed the more-precise-error-for-callable branch from 77e98b2 to 1b00107 Compare May 6, 2022 13:44
@JelleZijlstra JelleZijlstra self-assigned this May 6, 2022
@github-actions
Copy link
Contributor

github-actions bot commented May 6, 2022

According to mypy_primer, this change has no effect on the checked open source code. 🤖🎉

@hauntsaninja hauntsaninja merged commit 269adee into python:master May 7, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

mypy --strict has misleading suggestion for Callable
4 participants