Pyrefly v1.1.0-dev.2
Pre-releaseRelease date: June 10, 2026
About dev releases
Dev releases (versions likeX.Y.Z-dev.N) are non-stable snapshots cut periodically from trunk. They give early adopters a chance to try in-progress features and surface issues before the next stable release, but they don't carry the same stability or compatibility guarantees as a stable release — don't pin production projects to a dev version.
Pyrefly v1.1.0-dev.2 bundles 250 commits from 37 contributors.
✨ New & Improved
Type Checking
- Improved handling of defaults for function parameters annotated with type variables. Parameters like
x: T = 0now correctly validate their defaults against the type variable's constraints or bounds, and the default value is properly used when solving type variables in function calls. - Enhanced type narrowing for constrained type variables. Operations like
isinstancechecks and binary operations now preserve the type variable while correctly narrowing to specific constraints, fixing several false positives and negatives. - Improved handling of methods on type variables. When calling methods on a type variable (e.g.,
x.lower()wherex: TwithTconstrained tobytes | str), the return type now correctly preserves the type variable when the method returnsself's type. - Better support for shaped arrays across libraries. The tensor shape machinery now works with any array class that opts in via
shape_extensions.shaped_array, includingnumpy.ndarrayandjax.Array, not just PyTorch tensors. - Improved literal promotion and handling in function parameter defaults, making type inference more predictable when defaults include literal values.
- Fixed handling of binary operations and comparisons on constrained type variables, ensuring the type variable is preserved when appropriate rather than degrading to a union of constraints.
Language Server
- Literal value completions now work in more contexts. When assigning to an annotated variable, returning from a function, or setting an attribute with a
Literaltype, the editor now suggests the valid literal values. - New TSP endpoint
typeServer/getExpectedTypereturns the contextually expected type at a cursor position (e.g., the parameter type for a call argument, the declared type for an assignment), enabling richer IDE features. - Improved "move module member" refactoring. When moving a symbol to another module, Pyrefly now rewrites consumer imports automatically, updating
from source import footofrom target import fooacross the codebase. - New "move symbol to new file" refactoring creates a new file for a top-level symbol, moves the definition, and updates all consumer imports in one action.
- Enhanced pytest fixture support. Go-to-definition and find-references now work for pytest fixtures used as function parameters, navigating to the fixture definition.
- Better handling of non-Python modules in build systems. Go-to-definition on imports from
.thriftfiles and other non-Python modules now navigates to the module file when the specific symbol can't be resolved.
Coverage Reporting
- New
pyrefly coverage checkcommand provides a user-friendly way to verify type coverage meets a threshold, with configurable output formats and fail-under percentage. - Coverage reports now exclude symbols that can't be imported due to shadowed namespace packages, providing more accurate coverage metrics.
- Improved handling of stub re-exports. When a stub re-exports a class, the class's members are now correctly excluded from the coverage report to avoid inconsistent results.
- Coverage reports now respect
__all__in stubs more accurately, only treating imports as public re-exports when they appear in__all__or use theasalias syntax.
Error Reporting
- Error output is now significantly faster (up to 75% reduction in printing time for large error counts) through optimized rendering and buffering.
- New
--output-format junit-xmloption emits JUnit XML test reports, making it easier to integrate Pyrefly into CI dashboards. - Improved error messages for
None-related type mismatches. When passingT | NonewhereTis expected, the error now includes an actionable hint suggesting narrowing withis not Noneor widening the expected type. - Better error messages for missing overload matches, now including details about arity mismatches and specific argument type errors.
🐛 Bug fixes
We closed 24 bug issues this release 👏
- #3554: Fixed false-positive
unknown-nameerrors after short-circuit boolean operations. Code likeif SOMETHING_DEFINITELY_FALSE and A:no longer reportsAas unknown, since it's unreachable. - #3300: Fixed
unknown-namefalse positive when a name is introduced via a walrus operator in a decorator. Names defined with:=in decorator expressions are now visible after the decorated definition. - #1496, #3418, #3623: Fixed handling of defaults for function parameters with type variable annotations. Defaults like
x: T = 0are now validated correctly and used when solving type variables in calls. - #3059: Fixed
__getitem__resolution on type variables with constraints. Subscripting a type variable bounded byTypedDictor other subscriptable types now works correctly instead of falling back toobject.__getitem__. - #3603: Fixed type narrowing for discriminated
TypedDictunions when using membership tests. Expressions likeevent["ph"] in ("X", "C")now correctly narrow the union to matching members. - #3079, #3082: Fixed false-positive key errors after
key in dictchecks. When aTypedDictkey is tested within, subsequent subscript access no longer reports the key as possibly absent. - #3607: Fixed import resolution when using a config file. Bare imports like
from bar import functhat work at runtime now resolve correctly even when apyrefly.tomlis present, via the newenable-fallback-search-pathoption. - #357: Fixed unquoted forward reference handling in Python ≤3.13. Runtime-evaluated annotations now correctly report uninitialized forward names unless
from __future__ import annotationsis active. - #3536: Fixed
invalid-varianceerror location for overloaded methods. The error now appears on the offending overload signature rather than always pointing to the first overload. - #3671: Fixed stack overflow when a descriptor's
__get__is itself a descriptor. Self-referential descriptor patterns now terminate gracefully instead of crashing. - And more! #3235, #3673, #3541, #3684, #3647, #3632, #3626, #3640, #3641, #3639, #3645, #3701, #3664, #3598
Thank-you to all our contributors who found these bugs and reported them! Did you know this is one of the most helpful contributions you can make to an open-source project? If you find any bugs in Pyrefly we want to know about them! Please open a bug report issue here.
📦 Upgrade
pip install --upgrade pyrefly==1.1.0-dev.2How to safely upgrade your codebase
Upgrading the version of Pyrefly you're using or a third-party library you depend on can reveal new type errors in your code. Fixing them all at once is often unrealistic. We've written scripts to help you temporarily silence them. After upgrading, follow these steps:
pyrefly check --suppress-errors- Run your code formatter of choice
pyrefly check --remove-unused-ignores- Repeat until you achieve a clean formatting run and a clean type check.
This will add # pyrefly: ignore comments to your code, enabling you to silence errors and return to fix them later. This can make the process of upgrading a large codebase much more manageable.
Read more about error suppressions in the Pyrefly documentation.
🖊️ Contributors this release
@rchen152, @stroxler, @kinto0, @yangdanny97, @connernilsen, @grievejia, @NathanTempest, @jorenham, @samwgoldman, @asukaminato0721, David Tolnay, @lolpack, @mikeleppane, @maggiemoss, @MarcoGorelli, @JakobDegen, @arthaud, Anqi Wu, @terror, @bigfootjon, @aahanaggarwal, @rchiodo, @magic-akari, @SamB, @nitishagar, @ndmitchell, @NarxPal, Gregory Carlin, @javabster, @thatfunkymunki, @shobhitmehro, @hrolfurgylfa
Please note: These release notes summarize major updates and features. For brevity, not all individual commits are listed.