Skip to content

TSP: getComputedType returns null for nodes in files that aren't open (open vs closed files resolve differently) #4228

Description

@rchiodo

Summary

When Pyrefly runs as a Type Server (pyrefly tsp), a typeServer/getComputedType request for a Node (a { uri, range } pair) returns null whenever the target file is not open in the server — even though the file is on disk, reachable, and analyzed as part of checking an open file. Opening the same file (via textDocument/didOpen) makes the identical request return a valid Type. Open and closed files should resolve to the same type.

Environment

  • Reproduces on Pyrefly 1.0.0 and 1.2.0-dev.2 (latest dev), both started as pyrefly tsp.
  • Type Server Protocol typeServer/getComputedType, arg = Node { uri, range } (zero-based, LSP-style character offsets).

Expected behavior

getComputedType is a position/node-based query keyed by (uri, range). It should return the computed type for a node in any file the server can analyze, regardless of whether that file is currently open in the editor.

Actual behavior

  • Node in an open file → valid Type.
  • Same node in a file that is not open (but on disk and imported by an open file) → null.

Minimal repro (protocol level)

  1. initialize / initialized.

  2. textDocument/didOpen for main.py only:

    # main.py
    import lib
    x = lib.g()
    # lib.py  (on disk, NOT opened)
    def g() -> None: ...
  3. Send typeServer/getComputedType with arg.uri = lib.py and arg.range = the None return annotation of g. → Response: null.

  4. Now textDocument/didOpen for lib.py and repeat step 3 → a valid Type is returned.

Real-world impact

This surfaced in Pylance + Pyrefly-over-TSP as microsoft/pylance-release#8122. Pylance never sends didOpen for bundled stdlib stubs, so every node inside Pyrefly's bundled builtins.pyi (e.g. the None return annotation of object.__init__) returns null from getComputedType. It is not typeshed-specific — any unopened user file behaves the same way (repro above).

Note / hypothesis

It looks like Pyrefly only retains position→node/type resolution for open documents, and returns null for (uri, range) lookups into background/closed files. Ideally the lookup should work for any analyzable file.

Metadata

Metadata

Assignees

Labels

language-serverIssues specific to our IDE integration rather than type checking

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions