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

typing.NoReturn and typing.Never are somewhat unclear #117492

Closed
wyattscarpenter opened this issue Apr 3, 2024 · 2 comments
Closed

typing.NoReturn and typing.Never are somewhat unclear #117492

wyattscarpenter opened this issue Apr 3, 2024 · 2 comments
Labels
docs Documentation in the Doc dir topic-typing

Comments

@wyattscarpenter
Copy link

wyattscarpenter commented Apr 3, 2024

Documentation

In the typing docs, typing.Never and typing.NoReturn are somewhat unclear.

NoReturn used to be a type for function annotations when the function never returns. PEP 484 even says "The NoReturn type is only valid as a return annotation of functions, and considered an error if it appears in other positions". In practice, however, NoReturn was used as a bottom type, which eventually culminated in the addition of Never in #90633. However, it's still somewhat unclear from the typing docs exactly how you're supposed to use typing.Never and typing.NoReturn. In particular, are you supposed to prefer NoReturn for the return types of functions that never return?

Never

Never says, in part:

This can be used to define a function that should never be called, or a function that never returns

It then gives one example, a function never_call_me with an argument of type Never. Presumably this is the "a function that should never be called" case.

  • It should be stated emphatically that a function that has a Never in its argument types should never be called, if this the case.
    • Possibly, this sense of the would "should" should also be clarified. Is it a constraint on the user, the type system, or both?
  • If Never is also supposed to be used as the return type for a function that should be called but never returns, then this also needs an example.
    • If you're instead supposed to use NoReturn for that, then this fact should be mentioned here.
  • The documentation should also mention the claim "Type checkers should treat the two equivalently." from NoReturn, if that fact is in fact true.

NoReturn

NoReturn says, in part

NoReturn can also be used as a bottom type, a type that has no values. Starting in Python 3.11, the Never type should be used for this concept instead. Type checkers should treat the two equivalently.

  • It should be stated emphatically that a function that has a NoReturn in its argument types should never be called, if this the case.
  • It should be clarified that here "this concept" means using NoReturn as the type annotation of anything but a function return type, and not the entire concept of NoReturn as a whole. This could also be clarified by amending the first sentence in the quote from "NoReturn can also be used as a..." to "NoReturn can also be used as a type annotation in other positions as a...", perhaps.

Further information: https://typing.readthedocs.io/en/latest/spec/special-types.html#noreturn , https://typing.readthedocs.io/en/latest/spec/special-types.html#never, https://typing.readthedocs.io/en/latest/source/unreachable.html#never-and-noreturn

Linked PRs

@wyattscarpenter wyattscarpenter added the docs Documentation in the Doc dir label Apr 3, 2024
@JelleZijlstra
Copy link
Member

Thanks, feel free to submit a PR clarifying the documentation.

Never and NoReturn are exactly equivalent from a type checker's perspective and we should make the docs say so clearly. I suppose if we have to give a difference, we can say that NoReturn can be preferred for return types and Never for other places.

@TeamSpen210
Copy link

The reason a function with Never/NoReturn as an argument type can never be called is that the only places you get a variable with a type of Never is in code branches that the type checker thinks can never be reached. So any such function call can never be executed, without invalid types being used somewhere.

JelleZijlstra added a commit that referenced this issue May 3, 2024
Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
Co-authored-by: Erlend E. Aasland <erlend.aasland@protonmail.com>
miss-islington pushed a commit to miss-islington/cpython that referenced this issue May 3, 2024
…7678)

(cherry picked from commit 852263e)

Co-authored-by: Nice Zombies <nineteendo19d0@gmail.com>
Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
Co-authored-by: Erlend E. Aasland <erlend.aasland@protonmail.com>
JelleZijlstra added a commit that referenced this issue May 3, 2024
…#118547)

(cherry picked from commit 852263e)

Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
Co-authored-by: Nice Zombies <nineteendo19d0@gmail.com>
Co-authored-by: Erlend E. Aasland <erlend.aasland@protonmail.com>
SonicField pushed a commit to SonicField/cpython that referenced this issue May 8, 2024
Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
Co-authored-by: Erlend E. Aasland <erlend.aasland@protonmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs Documentation in the Doc dir topic-typing
Projects
None yet
Development

No branches or pull requests

5 participants