refactor(python): split FSharpRef.__init__ into overloads#4638
Merged
Conversation
The FSharpRef stub declared a single constructor with a union parameter:
def __init__(self, contents_or_getter: T | Callable[[], T],
setter: Callable[[T], None] | None = None) -> None
Pyright infers `T` from this fine, but Astral's `ty` cannot solve `T`
through the `T | Callable[[], T]` union for the getter/setter form: it
binds `T` to the getter callable itself, producing `FSharpRef[T]` that
it then rejects at every out-parameter call site (try_parse, byref
helpers, etc.).
Split the constructor into two overloads that mirror the two actual
construction modes — wrap a value, or wrap a getter/setter pair — so `T`
is unambiguously solvable from each. Runtime behaviour is unchanged and
the form is clearer.
This removes 178 false-positive `ty` diagnostics across the generated
Python output (tests 292 -> 118, library 72 -> 68) with no change to
Pyright (0 library / 34 tests, both unchanged) and all 2350 Python
tests passing.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Contributor
Python Type Checking Results (Pyright)
Excluded files with errors (4 files)These files have known type errors and are excluded from CI. Remove from
|
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
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The
FSharpRefstub declared a single constructor with a union parameter:This splits it into two overloads matching the two real construction modes — wrap a value, or wrap a getter/setter pair:
Motivation
Pyright infers
Tfrom the union form fine, buttycannot solveTthroughT | Callable[[], T]for the getter/setter form — it bindsTto the getter callable itself, yieldingFSharpRef[T]that it then rejects at every out-parameter call site (try_parse, byref helpers, etc.). The overloads makeTunambiguously solvable from each mode. Runtime behaviour is identical and the intent is clearer.This came out of an investigation into whether
tycould replace Pyright for this repo; the single-constructor union was the largest single source oftyfalse positives.Verification
tydiagnostics across the generated output../build.sh test python).🤖 Generated with Claude Code