Skip to main content

Lessons from Pyre that Shaped Pyrefly

· 10 min read

Pyrefly is a next-generation Python type checker and language server, designed to be extremely fast and featuring advanced refactoring and type inference capabilities. This isn’t the Pyrefly team’s first time building a type checker for Python: Pyrefly is a successor to Pyre, the previous type checker our team developed.

A lot of Pyrefly’s design comes directly from our experience with Pyre. Some things worked well at scale, while other things were harder to live with day-to-day. After running a type checker on massive Python codebases for a long time, we got a clearer sense of which trade-offs actually mattered to users.

This post is a write-up of a few lessons from Pyre that influenced how we approached Pyrefly.

pandas' Public API Is Now Type-Complete!

· 5 min read

At time of writing, pandas is one of the most widely used Python libraries. It is downloaded about half-a-billion times per month from PyPI, is supported by nearly all Python data science packages, and is generally required learning in data science curriculums. Despite modern alternatives existing, pandas' impact cannot be minimised or understated.

In order to improve the developer experience for pandas' users across the ecosystem, we at Quansight Labs (with support from the Pyrefly team at Meta) decided to focus on improving pandas' typing. Why? Because better type hints mean:

  • More accurate and useful auto-completions from VSCode / PyCharm / NeoVIM / Positron / other IDEs.
  • More robust pipelines, as some categories of bugs can be caught without even needing to execute your code.

By supporting the pandas community, pandas' public API is now type-complete (as measured by Pyright), up from 47% when we started the effort last year. We'll tell the story of how it happened - but first, we need to talk more about type completeness, and how we measure it.

Python Type Checker Comparison: Empty Container Inference

· 9 min read

Empty containers like [] and {} are everywhere in Python. It's super common to see functions start by creating an empty container, filling it up, and then returning the result.

Take this, for example:

def my_func(ys: dict[str, int]):
x = {}
for k, v in ys.items():
if some_condition(k):
x.setdefault("group0", []).append((k, v))
else:
x.setdefault("group1", []).append((k, v))
return x

This seemingly innocent coding pattern poses an interesting challenge for Python type checkers. Normally, when a type checker sees x = y without a type hint, it can just look at y to figure out x's type. The problem is, when y is an empty container (like x = {} above), the checker knows it's a list or a dict, but has no clue what's going inside.

The big question is: How is the type checker supposed to analyze the rest of the function without knowing x's type?

Third Party Stubs bundled with Pyrefly

· 3 min read

Since Pyrefly version 0.40, we've been bundling Typeshed third party stubs with every build, and since v0.46.0 we’ve been expanding beyond the stubs included with Typeshed to include stubs for select third party libraries as well. This ongoing effort brings enhancements to code navigation when using different libraries in your Python projects, and is part of our goal to make sure that the IDE experience can be used by as many people as possible. In this article, we’ll take a closer look at this feature and discuss how it can help you unlock the full potential of your IDE.

Making Pyrefly Diagnostics 18x Faster

· 7 min read

Hero image

As we move closer to a stable release of Pyrefly, our efforts have moved from expanding the language server’s capabilities to tackling performance edge cases. Recently, our friends at Astral alerted us to a specific edge case that is a great example of the kind of issues we’ve been aiming to uncover. The specific example Astral highlighted showed that in some edge cases Pyrefly could take multiple seconds to update diagnostics after editing. This is much slower than expected (used across Meta’s codebases, Pyrefly usually takes less than 10 milliseconds to recheck files after saving them) and prompted us to investigate further.

Now we’d like to share the story of how that edge case led us to rethink our underlying approach to diagnostics and dependency tracking, improving the speed at which Pyrefly's type errors update by 18x in the process.

4 Pyrefly Type Narrowing Patterns that make Type Checking more Intuitive

· 4 min read

If we view a type of an expression or variable as the set of possible values it can resolve to, narrowing is the process of applying constraints on those values. For example, if you have a variable x whose contents you don’t know, an if isinstance(x, int) check will narrow the type of x to int inside the body of the if-statement.

Since Python is a duck-typed language, programs often narrow types by checking a structural property of something rather than just its class name. For a type checker, understanding a wide variety of narrowing patterns is essential for making it as easy as possible for users to type check their code and reduce the amount of changes made purely to “satisfy the type checker”.

In this blog post, we’ll go over some cool forms of narrowing that Pyrefly supports, which allows it to understand common code patterns in Python.

Pyrefly Beta is here!

· 9 min read

Today we’re thrilled to announce that we have reached Beta status for Pyrefly, our open-source, high-performance tool for Python code navigation and type checking! We first announced Pyrefly back in April 2025, and thanks to incredible community feedback and a ton of work from our team, we’ve hit a significant milestone.

Bringing NumPy's type-completeness score to nearly 90%

· 7 min read

Because NumPy is one of the most downloaded packages in the Python ecosystem, any incremental improvement can have a large impact on the data science ecosystem. In particular, improvements related to static typing can improve developer experience and help downstream libraries write safer code. We'll tell the story about how we (Quansight Labs, with support from Meta's Pyrefly team) helped bring its type-completeness score to nearly 90% from an initial 33%.