Skip to content

[ty] disallow explicit specialization of type variables themselves#21938

Merged
carljm merged 7 commits intoastral-sh:mainfrom
mtshiba:ban-typevar-specialization
Dec 12, 2025
Merged

[ty] disallow explicit specialization of type variables themselves#21938
carljm merged 7 commits intoastral-sh:mainfrom
mtshiba:ban-typevar-specialization

Conversation

@mtshiba
Copy link
Collaborator

@mtshiba mtshiba commented Dec 12, 2025

Summary

This PR makes explicit specialization of a type variable itself an error, and the result of the specialization is Unknown.

The change also fixes astral-sh/ty#1794.

Test Plan

mdtests updated
new corpus test

@astral-sh-bot
Copy link

astral-sh-bot bot commented Dec 12, 2025

Diagnostic diff on typing conformance tests

No changes detected when running ty on typing conformance tests ✅

@astral-sh-bot
Copy link

astral-sh-bot bot commented Dec 12, 2025

mypy_primer results

Changes were detected when running on open source projects
scikit-build-core (https://github.com/scikit-build/scikit-build-core)
+ src/scikit_build_core/build/wheel.py:98:20: error[no-matching-overload] No overload of bound method `__init__` matches arguments
- Found 41 diagnostics
+ Found 42 diagnostics

No memory usage changes detected ✅

@mtshiba mtshiba marked this pull request as ready for review December 12, 2025 12:18
@AlexWaygood AlexWaygood added the ty Multi-file analysis & type inference label Dec 12, 2025
@mtshiba mtshiba force-pushed the ban-typevar-specialization branch from b40e802 to a4585f7 Compare December 12, 2025 12:32

T = TypeVar("T")
ImplicitPositive = T
Positive: TypeAlias = T
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This usage seems to be used in bokeh, so we should allow it.

Copy link
Contributor

Choose a reason for hiding this comment

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

For reference, pyright and pyrefly support both ImplicitPositive and Positive forms. Mypy supports only the explicit PEP 613 version.

With our current implementation of implicit type aliases, it would be quite difficult for us to distinguish ImplicitPositive from direct use of T. This may change in the future, but for now it seems fine to match mypy's support.

Copy link
Contributor

@carljm carljm left a comment

Choose a reason for hiding this comment

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

Looks good, thanks! A few nits, I will just make some minor updates and then merge.


T = TypeVar("T")
ImplicitPositive = T
Positive: TypeAlias = T
Copy link
Contributor

Choose a reason for hiding this comment

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

For reference, pyright and pyrefly support both ImplicitPositive and Positive forms. Mypy supports only the explicit PEP 613 version.

With our current implementation of implicit type aliases, it would be quite difficult for us to distinguish ImplicitPositive from direct use of T. This may change in the future, but for now it seems fine to match mypy's support.

/// `T = TypeVar("T")`
Legacy,
/// `Alias: typing.TypeAlias = T`
Pep613,
Copy link
Contributor

Choose a reason for hiding this comment

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

This variant is unlike the others -- it is not really a kind of typevar, but rather a kind of type alias -- a direct alias to a typevar.

I think this is the most direct implementation, but I would probably name and document this variant so as to emphasize its differentness more.

@carljm carljm merged commit e19c050 into astral-sh:main Dec 12, 2025
42 checks passed
dcreager added a commit that referenced this pull request Dec 13, 2025
* origin/main:
  [ty] disallow explicit specialization of type variables themselves (#21938)
  [ty] Improve diagnostics for unsupported binary operations and unsupported augmented assignments (#21947)
  [ty] update implicit root docs (#21955)
dcreager added a commit that referenced this pull request Dec 13, 2025
* origin/main: (22 commits)
  [ty] Allow gradual lower/upper bounds in a constraint set (#21957)
  [ty] disallow explicit specialization of type variables themselves (#21938)
  [ty] Improve diagnostics for unsupported binary operations and unsupported augmented assignments (#21947)
  [ty] update implicit root docs (#21955)
  [ty] Enable even more goto-definition on inlay hints (#21950)
  Document known lambda formatting deviations from Black (#21954)
  [ty] fix hover type on named expression target (#21952)
  Bump benchmark dependencies (#21951)
  Keep lambda parameters on one line and parenthesize the body if it expands (#21385)
  [ty] Improve resolution of absolute imports in tests (#21817)
  [ty] Support `__all__ += submodule.__all__`
  [ty] Change frequency of invalid `__all__` debug message
  [ty] Add `KnownUnion::to_type()` (#21948)
  [ty] Classify `cls` as class parameter (#21944)
  [ty] Stabilize rename (#21940)
  [ty] Ignore `__all__` for document and workspace symbol requests
  [ty] Attach db to background request handler task (#21941)
  [ty] Fix outdated version in publish diagnostics after `didChange` (#21943)
  [ty] avoid fixpoint unioning of types containing current-cycle Divergent (#21910)
  [ty] improve bad specialization results & error messages (#21840)
  ...
@mtshiba mtshiba deleted the ban-typevar-specialization branch December 15, 2025 08:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ty Multi-file analysis & type inference

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Stack overflows on type parameters with invalid recursive bounds

3 participants