Anonymous View
Skip to content

generics: specify TypeVar-default inference when parameter default matches#2313

Open
ashishpatel26 wants to merge 1 commit into
python:mainfrom
ashishpatel26:fix/2213-typevar-default-function-call
Open

generics: specify TypeVar-default inference when parameter default matches#2313
ashishpatel26 wants to merge 1 commit into
python:mainfrom
ashishpatel26:fix/2213-typevar-default-function-call

Conversation

@ashishpatel26

Copy link
Copy Markdown

Summary

Fixes #2213.

The spec's "Function Defaults" section previously left all generic-function TypeVar default semantics unspecified. However, there is a concrete, well-defined case that can and should be specified:

When a TypeVar S with default D is used as the type of exactly one parameter p, and p's default argument value is assignable to D, calling the function without p must infer S = D.

Additionally, the function definition is valid in this case: the default argument is checked against D (the TypeVar's default), not against the free TypeVar S itself.

This is already the behavior of pyright (and pyrefly, pycroscope) — the spec is simply catching up.

Changes

  • docs/spec/generics.rst — "Function Defaults" section: keep the general caveat but carve out and specify this concrete case with an example
  • conformance/tests/generics_defaults.py — new test section with a Getter[T] class whose .get() has S=None default
  • Checker TOMLs updated:
    • pyright, pyrefly, pycroscope — pass (no change to Pass status)
    • mypy, zuban — incorrectly reject the function definition → Partial
    • ty — incorrectly rejects the function definition, but correctly infers return types → Partial

Checker behaviour at a glance

Checker def get(..., default: S = None) getter.get()str | None
pyright ✅ valid
pyrefly ✅ valid
pycroscope ✅ valid
mypy ❌ rejects (false positive)
zuban ❌ rejects (false positive)
ty ❌ rejects (false positive)

Test plan

  • conformance/src/main.py --report-only produces a clean results.html
  • validate_results.py passes (Fail results have conformant field)

…tches

The spec's "Function Defaults" section previously said generic function
TypeVar defaults are "unspecified" in all cases.  However, there is a
concrete, well-defined case that can and should be specified: when a
TypeVar S with default D is used as the type of exactly one parameter p,
and p's default argument value is assignable to D, calling the function
without p must be type-checked as if p's default value were passed
explicitly.  Type checkers must therefore infer S = D.

Additionally, the function definition itself is valid in this case:
the default argument is checked for assignability against D (the TypeVar's
default type), not against the free TypeVar S.

Spec change: docs/spec/generics.rst — "Function Defaults" section
Conformance test: new section at end of generics_defaults.py using a
Getter[T] class whose .get() method has S=None default.

Checker results:
  pyright, pyrefly, pycroscope — pass all new assertions
  mypy, zuban — incorrectly reject the function definition (Partial)
  ty — incorrectly rejects the function definition; correctly infers
       the return types (Partial)

Fixes: python#2213
@srittau srittau added the topic: typing spec For improving the typing spec label Jun 22, 2026
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.

spec/conformance: function with TypeVar default and default argument used in context.

2 participants