Skip to content

Treat type inference which produces <nothing> as an error or warning under --strict mode #15931

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

Closed
sirosen opened this issue Aug 22, 2023 · 7 comments
Labels

Comments

@sirosen
Copy link

sirosen commented Aug 22, 2023

Feature

If a type is inferred as <nothing> and --strict was used, treat this as an error or warning.
Include a --disallow-nothing/--allow-nothing flag and disallow_nothing config value, or --warn-nothing/--no-warn-nothing flag and variable to control the behavior more granularly.

Pitch

From #3924, it was suggested that I open a new issue.

The following type alias produces <nothing> as the inferred return type of a function:

from typing import TypeVar, Callable
T = TypeVar('T')

F = Callable[[T], T]
def test() -> F[T]: ...
reveal_type(test) # Revealed type is 'def [T] () -> def (T`-1) -> T`-1'
reveal_type(test()) # Revealed type is 'def (<nothing>) -> <nothing>'

In #3924, this is described as a bug with the binding of T in greater detail. #3924 also includes a comment stating that <nothing> is a bottom type. I have also heard typing.Never/typing.NoReturn referred to as a bottom type, but those types are useful and desirable -- so much so that users can refer to them directly and they are part of the stdlib.

I've never wanted to produce <nothing> -- I didn't even know it existed until recently, after several years of using mypy.

My use-case is... pallets/click#2558 . A bug in a mainstream library which was trying to do everything correctly, but didn't get any warning about shipping types which produced <nothing>.
For click specifically, there are now typing tests with assert_type, so this is unlikely to recur. But if any other library were to produce <nothing> -- or, more nefariously, a type like def [T] () -> def (T`-1) -> T`-1 which can result in <nothing> -- it would be best to be able to catch it early, via the type checker.

@sobolevn
Copy link
Member

assert_never has exactly the same signature: (<nothing>) -> <nothing>, it is a possible signature, it is not an error generally.

So, I don't think that this flag is possible. Testing types is the solution here, in my opinion.

@sirosen
Copy link
Author

sirosen commented Aug 24, 2023

I agree that testing types is the best solution.

Other than assert_never, are there valid scenarios in which users could be handling <nothing>? It's a very unusual type because a user can't write it explicitly -- unlike Never.

I'm hesitant to self-close this issue because what seems to have happened in click is that inference "fell through" in some way to (<nothing>) -> <nothing>. So whatever caused that to happen seems like a scenario in which mypy could warn that normal type inference didn't work?

@sobolevn
Copy link
Member

Never as a return type is quite common, it is not as common as a parameter.

@sirosen
Copy link
Author

sirosen commented Aug 24, 2023

Are you saying that <nothing> is the same as Never?

I have written plenty of functions with -> Never. But I had never seen the type <nothing> until quite recently.

@sobolevn
Copy link
Member

sobolevn commented Aug 24, 2023

Yes, <nothing> is Never's (and NoReturn's) text representation.

@sirosen
Copy link
Author

sirosen commented Aug 24, 2023

Oh, then this issue report makes no sense! I'll self-close.

I don't suppose we could make the str of it typing.Never? I've been laboring under the assumption that this was an internal mypy type which acted as some kind of other bottom type.

@sirosen sirosen closed this as not planned Won't fix, can't repro, duplicate, stale Aug 24, 2023
@sobolevn
Copy link
Member

Hm, I don't know :)
You can open a new issue about it, let's see what other people think.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants