facebook / facebook/pyrefly

User-extensible version tests that are evaluated at type inference time

Open
#2,652 1 comment 1 reaction 0 assignees View on GitHub
typechecking
Dominant language
Rust
Stars
7k
Forks
516
PR merge metrics
No merged PRs in 30d

Description

### Describe the Bug

I'm wondering if there's a way to achieve the following in pyrefly:

Suppose `amodule` contains a function `f` whose signature was `f(str)` in version 1, but became `f(int)` in version 2.

Might it be possible for the following program to type check?
```
import amodule

if amodule.version < 2:
f("hello")
else:
f(42)
```
i.e., *only* one branch is type checked, and which depends on the version of `amodule` that is installed and its type stubs.

There are already certain values that pyrefly will evaluate statically, e.g., `TYPE_CHECKING` or `sys.version_info`. Is it possible for users to extend to that list by any means or to annotate `version` in some way such that this happens? Could there be?

One guess I had was that annotating `version: Literal[2]` might work, but sadly it does not.

(Motivating use case from JAX: we allow users to use the head Python code (`jax`) with the released C++ code (`jaxlib`) so you don't need to build anything to change the Python. So it's very common to need to use a version test to work out which version of the C++ code the Python code is using. This is no problem for Python evaluation itself, but the same issue arises for static type checks. You might say: "you shouldn't make breaking changes to your APIs", but these are private APIs and breaking users is not a problem.)

### Sandbox Link

_No response_

### (Only applicable for extension issues) IDE Information

_No response_

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.