From 454fd5ccc2924ce3e65c2a000818c0813d0fd3ac Mon Sep 17 00:00:00 2001 From: Dag Brattli Date: Tue, 9 Jun 2026 23:30:27 +0200 Subject: [PATCH] refactor(python): split FSharpRef.__init__ into overloads MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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) --- src/fable-library-py/fable_library/core/types.pyi | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/fable-library-py/fable_library/core/types.pyi b/src/fable-library-py/fable_library/core/types.pyi index 075daa55e2..31954e4ea4 100644 --- a/src/fable-library-py/fable_library/core/types.pyi +++ b/src/fable-library-py/fable_library/core/types.pyi @@ -1,7 +1,11 @@ from collections.abc import Callable +from typing import overload class FSharpRef[T]: - def __init__(self, contents_or_getter: T | Callable[[], T], setter: Callable[[T], None] | None = None) -> None: ... + @overload + def __init__(self, contents_or_getter: T) -> None: ... + @overload + def __init__(self, contents_or_getter: Callable[[], T], setter: Callable[[T], None]) -> None: ... @property def contents(self) -> T: ... @contents.setter