FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

spec: expand Never/NoReturn with precise subtyping rules by ashishpatel26 · Pull Request #2309 · python/typing · GitHub

Repository navigation

spec: expand Never/NoReturn with precise subtyping rules - #2309

Open
ashishpatel26 wants to merge 5 commits into
python:mainfrom
ashishpatel26:fix/1458-never-noreturn-spec
Open

ashishpatel26 wants to merge 5 commits into
python:mainfrom
ashishpatel26:fix/1458-never-noreturn-spec

Conversation

Copy link
Copy Markdown
Contributor

Summary

Resolves #1458.

The Never section in the spec was four lines with no subtyping rules. Type checkers (mypy, pyright, pyrefly, zuban) all converge on a consistent set of behaviours, but none were written down, making the spec unexecutable for implementers and leaving the community guessing.

This PR codifies what the implementations already agree on:

  • Never is a subtype of every fully static type (bottom type property)
  • No type other than Never (and Any) is a subtype of Never
  • Never | T is equivalent to T for any T
  • In covariant type parameter positions, Container[Never] is assignable to Container[T] for any T; in invariant positions, the normal invariance rules apply
  • type[Never] is a valid annotation representing an uninhabitable class
  • Clarify that NoReturn may appear in non-return-type positions (the old restriction was removed)

Changes

File Change
docs/spec/special-types.rst Expand Never from 4 lines to a full subtyping specification
conformance/tests/specialtypes_never.py Add 6 new test cases covering union collapse, type[Never], and invariance
conformance/results/*/specialtypes_never.toml Updated results for mypy, pyright, pyrefly, zuban (all Pass); ty marked Partial (misses two of the new error cases)

Conformance results snapshot

Checker Result Notes
mypy Pass All 5 expected errors flagged
pyright Pass All 5 expected errors flagged
pyrefly Pass All 5 expected errors flagged
zuban Pass All 5 expected errors flagged
ty Partial Misses object → Never and list[Never] → list[int] errors

Out of scope

The LSP/mutable-attribute debate from #1458 (whether class B(A): foo: Never should be an error) is left for a separate issue. That requires formalising mutable attribute override rules — a larger change that should not block landing the uncontroversial subtyping rules documented here.

…hon#1458)

The previous spec described Never in four lines without defining any of
its subtyping behaviour. Type checkers converge on a consistent set of
rules, but none were written down. This commit codifies them.

Spec changes (docs/spec/special-types.rst):
- Never is a subtype of every fully static type (bottom type property)
- No type other than Never (and Any) is a subtype of Never
- Never | T collapses to T for any type T
- Never as a type argument: covariant containers accept it,
  invariant containers do not
- type[Never] represents an uninhabitable class object
- Clarify that NoReturn may appear in non-return positions

Conformance test changes (conformance/tests/specialtypes_never.py):
- Add func11: Never | int collapses to int
- Add func12: object is not assignable to Never (E)
- Add func13: raise in Never-returning function is OK
- Add func14: type[Never] is a valid annotation
- Add func15: list[Never] return is valid
- Add func16: list[Never] is not assignable to list[int] (E)

Result TOMLs updated for mypy, pyright, pyrefly, zuban (Pass).
ty marked Partial: does not flag func12 and func16 errors.

Closes python#1458
srittau added the topic: typing spec For improving the typing spec label Jun 22, 2026

JelleZijlstra left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

I don't think this verbiage is necessary. This isn't the kind of issue that can be fixed by adding some text without much understanding.

Comment thread docs/spec/special-types.rst Outdated
Comment thread docs/spec/special-types.rst Outdated
Comment thread docs/spec/special-types.rst Outdated
Comment thread docs/spec/special-types.rst Outdated
Comment thread docs/spec/special-types.rst Outdated
- Use int instead of object as the non-Never witness (object is already
  expected to not be a subtype of most things; int is more illuminating)
- Rephrase to avoid the too-strong 'No type other than Never' claim
  (uninhabitable types like tuple[Never, int] are also subtypes of Never)
- Qualify all 'every type T' as 'every fully static type T' throughout
  (the subtype relation is undefined for gradual types like Any)
- Replace list[Never] with Sequence[Never] in the covariant example
  (list is invariant, so list[Never] is not assignable to list[int];
  Sequence is covariant and correctly demonstrates the bottom-type behaviour)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

topic: typing spec For improving the typing spec

Projects

None yet

Development

Successfully merging this pull request may close these issues.

NoReturn and Never are underspecified in the spec

4 participants


Back | FazBrowse Home | New Git URL