Release date: June 17, 2026
Pyrefly v1.1.0 bundles 250 commits from 25 contributors.
✨ New & Improved
Type Checking
- Pyrefly now correctly narrows
TypedDicttypes afterisinstance(x, dict)checks, treating them as runtimedictinstances while preserving field information in the positive branch. - Type narrowing for bounded and constrained
TypeVars has been significantly improved.isinstancechecks now correctly narrowSelfand bounded type variables via their disjoint-base representatives, and negative narrowing on bounded TypeVars no longer produces false positives. - Constrained
TypeVars are now preserved through method calls and binary operations, soT & intwhereT: (int, str)correctly returnsT & intinstead of losing the TypeVar. - Classes decorated with
@dataclass(slots=True)are now recognized as PEP 800 disjoint bases when they synthesize non-empty__slots__, enabling proper multiple-inheritance conflict detection and type narrowing. - Pyrefly now detects when methods override parent class methods without using the
@overridedecorator, and a new quick fix can automatically add the decorator for you. - Variance inference now correctly skips receiver parameters (like
selfandcls) when determining class variance, fixing false invariance reports for container-like classes.
Performance
- File discovery now uses the
ignorecrate with parallel traversal, making initial indexing 2-3x faster and dramatically reducing wall-clock time for large projects. - Completed calculation results are now stored outside the mutex, reducing lock contention and improving performance on large codebases like
homeassistant-coreandtransformers. - Implicit builtins are now lazily materialized on first use instead of eagerly adding hundreds of import bindings to every module, reducing memory usage by 5-13% and CPU time by 10-28%.
- Literal unions are now capped at 256 non-enum literals or 4096 enum members per kind to prevent exponential type growth, and overall union size is capped at 4096 members.
- Bytes literals larger than 1024 bytes are now widened to
bytesto keep type representations bounded. - Wide tuple unions (more than 8 variants) are now collapsed into unbounded tuple types to prevent performance hangs and out-of-memory errors during type checking.
Language Server
- Hover tooltips now work correctly on subscript expressions without spaces (e.g.,
c[0]), showing the__getitem__signature instead of garbled output. - Literal completions are now offered in expected-type contexts like annotated assignments, return statements, and attribute targets, not just call arguments.
- Dictionary key completions now work in empty subscripts (
d[) and half-typed subscripts (d["), suggesting known keys fromTypedDicts and narrowed facets. - Go-to-definition on
from X import Ystatements now falls back to the module file when the imported name can't be resolved (e.g., for non-Python modules like.thriftfiles). - Quick fixes now use the file's actual line ending (CRLF or LF) instead of hardcoded
\n, preventing mixed line endings. - Added support for legacy pkgutil-style namespace packages
Type Server Protocol (TSP)
- The TSP backend now emits resolvable
typingclasses andTypeVars instead of opaque builtins, so hovering over special forms likeLiteral,Final, andParamSpecnow shows the correct name instead ofUnknown. - Function types in TSP responses now carry specialized parameter and return types, enabling Pylance to display real types instead of
Unknown. - Pyrefly now emits the protocol-conformant lowercase
unknownsentinel in TSP responses instead of uppercaseUnknown. - Expected-type queries now return the contextually expected type (e.g., the parameter type for a call argument) instead of the computed type, making the
typeServer/getExpectedTyperequest actually useful.
Error Reporting
- No-matching-overload errors now show only the parameters relevant to the arguments you passed, hiding irrelevant optional parameters to make signatures easier to read.
- Arity mismatch details and call errors are now included in no-matching-overload error messages, making it clearer why an overload didn't match.
- The
Nonehint in error messages now only suggests narrowing when it makes sense (e.g., in conditionals) and only suggests adding| Nonewhen you control the type. - Variance errors on overloaded methods now point to the offending overload instead of always pointing to the first one.
Configuration
- The
tensor-shapesconfig option has been removed. Tensor shape support is now automatically derived from whethershape_extensionsis resolvable for the module being checked. - Pyrefly now understands
$MYPY_CONFIG_FILE_DIRwhen migrating mypy configs, stripping it to produce portable relative paths. - Glob patterns in config files now require
/separators (not OS-specific separators) for cross-platform consistency.
🐛 Bug fixes
We closed 89 bug issues this release 👏
- #3671: Fixed a stack overflow crash when a descriptor's
__get__method is itself a descriptor. Pyrefly now detects this self-referential case and terminates instead of recursing indefinitely. - #3712: Fixed a crash when instantiating a nested functional
NamedTuplein constructor defaults. Pyrefly now callsensure_expron the default value to avoid panicking during binding. - #3789: Fixed a panic ("a variable has leaked from one module to another") when opening
sympy/core/expr.pyin the LSP. The lambda parameter cache is now keyed by(ModuleName, ModulePath, LambdaParamId)to distinguish in-memory and on-disk module versions. - #3749: Fixed a false positive
incompatible-overload-residualerror onfunctools.reduce(operator.*, ...). The overload resolves correctly; the spurious diagnostic has been removed. - #3819: Fixed
unsupported-operationerrors when matching on overloads. Protocol conformance now filters overloads byself:type, so atimedeltareceiver correctly selects the matching overload instead of erroneously picking the first one. - #3751: Pyrefly now rejects
@dataclassdecorators onNamedTupleclasses, matching CPython's runtime behavior which raises aTypeError. - #3773: Optional imports like
try: import a except ImportError: a = Noneare no longer reported as untyped bypyrefly coverage. - #357: Runtime-evaluated annotations now report uninitialized forward names for Python < 3.14 unless
from __future__ import annotationsis active, matching CPython's behavior. - #3624:
pyrefly coverage reportno longer includes definitions fromif __name__ == "__main__"guards, as those aren't importable at runtime. - #3387:
Foo[Bar]underfrom __future__ import annotationsnow bindsBaras static type information whenFoois a known class, avoiding false "uninitialized" diagnostics. - And more! #2798, #3188, #3385, #3208, #3237, #3378, #3413, #3455, #3392, #3299, #3446, #3448, #3396, #1492, #2451, #3431, #3210, #3381, #2547, #3147, #3524, #3506, #3519, #3343, #3505, #3369, #3344, #3400, #3394, #3221, #3514, #3520, #3544, #3458, #3593, #3548, #3576, #3292, #3526, #2869, #3228, #3578, #3568, #3410, #3602, #3300, #3356, #3607, #3612, #1496, #3623, #3059, #3598, #3536, #3066, #3418, #3235, #3673, #3541, #3169, #3075, #1838, #3550, #955, #2711, #498, #3113, #3197, #3215, #1592, #2002, #2082, #2199, #2553, #2693, #3220, #2751, #3743, #3790, #3708, #3703
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.0How 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, @grievejia, @kinto0, @yangdanny97, @jorenham, @samwgoldman, @connernilsen, @stroxler, @shobhitmehro, @asukaminato0721, @javabster, @NathanTempest, David Tolnay, @mikeleppane, @maggiemoss, @arthaud, Eric Hou, Gregory Carlin, @thatfunkymunki, @hrolfurgylfa, @nitishagar, @tobyh-canva, @vivekjm, @QEDady, @rchiodo, @mdbernard
Please note: These release notes summarize major updates and features. For brevity, not all individual commits are listed.