Resolve TSP type queries in files that aren't open (#4235)#4235
Open
kinto0 wants to merge 1 commit into
Open
Conversation
Contributor
|
@kinto0 has exported this pull request. If you are a Meta employee, you can view the originating Diff in D113135763. |
Summary: TSP `getComputedType` (and `getDeclaredType`/`getExpectedType`) returned `null` for any node in a file that wasn't open in the editor, even though the file was on disk, reachable, and analyzed as a dependency of an open file. Opening the same file made the identical `(uri, range)` query succeed. This broke every node in Pyrefly's bundled stdlib stubs (e.g. `builtins.pyi`), which clients like Pylance never `didOpen`. Fixes facebook#4228. The root cause: `computed_type_at_range` and `open_at_position` built the handle with `make_open_handle`, which always uses `ModulePath::memory`. In-memory content only exists for opened files, so the memory-keyed handle only matched open documents; closed files are keyed under `FileSystem` or `BundledTypeshed` handles (whose `SysInfo` is inherited from the importer and can't be reconstructed here), so the lookup missed and short-circuited to `null`. New helper `query_transaction_and_handle` resolves a path to the handle the checker actually analyzes it under: - open files -> in-memory overlay (unchanged fast path); - otherwise reuse the already-loaded handle: the filesystem handle when it can be rebuilt directly, else a by-path scan that reuses the loaded `BundledTypeshed` handle so stdlib queries don't re-check typeshed; - fall back to a fresh filesystem handle read from disk when the file hasn't been analyzed yet. It then forces a full solve at `Require::Everything`, the only level that retains bindings/answers — exactly the data the type lookup reads — so the result is available regardless of what require level the file was loaded at as a dependency. Open-file queries are unchanged; only the previously `null` closed-file path does additional work, and bundled typeshed reuses its already-solved handle. Differential Revision: D113135763
kinto0
force-pushed
the
export-D113135763
branch
from
July 21, 2026 23:47
350ee71 to
4158781
Compare
|
According to mypy_primer, this change doesn't affect type check results on a corpus of open source code. ✅ |
rchiodo
approved these changes
Jul 22, 2026
stroxler
approved these changes
Jul 23, 2026
stroxler
left a comment
Contributor
There was a problem hiding this comment.
Review automatically exported from Phabricator review in Meta.
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:
TSP
getComputedType(andgetDeclaredType/getExpectedType) returnednullfor any node in a file that wasn't open in the editor, even thoughthe file was on disk, reachable, and analyzed as a dependency of an open
file. Opening the same file made the identical
(uri, range)querysucceed. This broke every node in Pyrefly's bundled stdlib stubs (e.g.
builtins.pyi), which clients like Pylance neverdidOpen.Fixes #4228.
The root cause:
computed_type_at_rangeandopen_at_positionbuilt thehandle with
make_open_handle, which always usesModulePath::memory.In-memory content only exists for opened files, so the memory-keyed handle
only matched open documents; closed files are keyed under
FileSystemorBundledTypeshedhandles (whoseSysInfois inherited from the importerand can't be reconstructed here), so the lookup missed and short-circuited
to
null.New helper
query_transaction_and_handleresolves a path to the handle thechecker actually analyzes it under:
can be rebuilt directly, else a by-path scan that reuses the loaded
BundledTypeshedhandle so stdlib queries don't re-check typeshed;hasn't been analyzed yet.
It then forces a full solve at
Require::Everything, the only level thatretains bindings/answers — exactly the data the type lookup reads — so the
result is available regardless of what require level the file was loaded
at as a dependency. Open-file queries are unchanged; only the previously
nullclosed-file path does additional work, and bundled typeshed reusesits already-solved handle.
Differential Revision: D113135763