Skip to content

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

Closed as not planned

Description

@sirosen

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.

Activity

  1. sobolevn commented on Aug 24, 2023

    @sobolevn
    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.

  2. sirosen commented on Aug 24, 2023

    @sirosen
    Author

    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?

  3. sobolevn commented on Aug 24, 2023

    @sobolevn
    Member

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

  4. sirosen commented on Aug 24, 2023

    @sirosen
    Author

    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.

  5. sobolevn commented on Aug 24, 2023

    @sobolevn
    Member

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

  6. sirosen commented on Aug 24, 2023

    @sirosen
    Author

    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.

  7. sobolevn commented on Aug 24, 2023

    @sobolevn
    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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions