pypi / ruff
ruff
What changed in ruff 0.15 to 0.17, from its official release notes, upgrade guides and advisories. Sources checked 2026-10-18.
23 breaking6 security1 deprecations24 new APIs and options16 performance65 behavior and defaults17 tooling122 fixes and other
See which of these apply to your code, ranked, in your agent:
npx @unstale/cli initruff 0.1735 changes
Breaking changes 5
flake8-builtins expands its checks in class scopes.
The conda-forge build no longer depends on Python, so python -m ruff and import ruff no longer work; use ruff directly from PATH.
Support for the legacy Python language server has been removed.
When neither target-version nor requires-python configures a Python version, Ruff now defaults to Python 3.11 instead of Python 3.10.
The formatter and I001, E501, and W505 consistently ignore trailing pragma comments when computing line length; existing imports may be reformatted.
Security 1
macOS and Windows release executables and Ruff wheels are code-signed; macOS executables are also notarized, enabling publisher and binary-integrity verification.
Deprecations 1
ruff.nativeServer is deprecated and ignored because the Ruff VS Code extension now always uses the native language server.
New APIs and options 1
flake8-type-checking adds the notion of runtime-ambiguous references.
Behavior and default changes 16
The pycodestyle rules no longer treat None, True, or False as keywords.
More collections and weakref containers are treated as mutable.
The preview flake8-bugbear rule now reports the method name and a more precise range.
These flake8-datetimez rules are no longer enabled by default.
The default full output format now shows unsafe fixes and suggestions requiring manual review regardless of unsafe-fixes; applying unsafe fixes still requires explicit opt-in.
flake8-type-checking no longer flags annotations in function scopes.
The refurb fix is marked unsafe and the rule moves to suspicious.
datetime as dt is now recognized as a conventional alias by flake8-import-conventions.
JUnit output uses a skipped attribute instead of disabled on testsuite elements and adds a skipped attribute to the root testsuites element.
The TID255 rule is stabilized and no longer in preview.
The TID254 rule is stabilized and no longer in preview.
The default regex now recognizes underscore-prefixed Unicode names, such as _次, as dummy variables.
The RUF071 rule is stabilized and no longer in preview.
The preview Ruff rule allows docstrings in strict mode.
When checking for syntax errors without a configured Python version, Ruff now defaults to Python 3.15 instead of Python 3.14.
Ruff uses Unicode 17 data for identifier normalization and named character escapes.
Tooling 2
The conda-forge build now supports linux-riscv64, win-arm64, and linux-ppc64le platforms.
pyupgrade now suggests typing.TypeForm on Python 3.15.
Fixes and other changes 9
Fixes dedent behavior when there are multiple leading comments.
The rules no longer suggest invalid comprehensions.
Fixes false positives on quoted annotations.
The rule now detects legacy positional-only parameters in __new__ methods.
The fix is marked unsafe when it creates a docstring.
The useless-return fix now preserves trailing comments.
Avoids a false positive when pytest.raises is used in a with statement.
flake8-self allows private access on object.__new__(cls) instances.
flake8-tidy-imports skips lazy-import-mismatch in stubs.
ruff 0.16133 changes
Breaking changes 6
DTZ901 rejects
tzinfo=Nonefor datetime bounds.Syntax errors now detect duplicate keyword arguments.
Semantic syntax errors in string type definitions are now emitted as F722.
Ruff enables 413 rules by default, up from 59, while removing 18 more opinionated E and F rules from the default set.
Checks additional PEP 585-compatible APIs, such as those from collections.abc.
The filename, location, end_location, and fix edit location fields may now be null instead of default values.
Security 5
The server avoids running
uv formatin untrusted workspaces.Embeds archive checksums in the shell installer.
Checks keyword arguments as well as other arguments.
Checks keyword arguments as well as other arguments.
Checks keyword arguments as well as other arguments.
New APIs and options 10
Adds a pyupgrade rule for context manager iterator annotations.
Adds
extend-banned-apiconfiguration forflake8-tidy-imports.Ruff recognizes the
parent_modeargument forRUF064andPTH103.Adds a preview rule for default values on method receivers.
Category selectors are introduced for selecting rules.
Adds a rule to replace
while 1withwhile True.An option lets developers opt out of human-readable names.
Ruff can format Python code blocks in Markdown files and does so by default.
Supports the same output formats as the linter, including github and gitlab for CI annotations.
Suppression comments can appear at the end of a line or on the line preceding a diagnostic, like noqa comments.
Performance 4
Reduces memory used by diagnostics.
Speeds up inherited configuration resolution.
Ruff releases now enable PGO for Linux x86-64, Linux ARM64, Windows x86-64, and macOS ARM64.
The unnecessary-future-import rule is faster.
Behavior and default changes 35
Ruff supports
__lazy_modules__, including conditional assignments.On Python 3.15 and later, Ruff prefers lazy imports over
TYPE_CHECKINGimports.On Python 3.15 and later, Ruff prefers lazy imports over
TYPE_CHECKINGimports.On Python 3.15 and later, Ruff prefers lazy imports over
TYPE_CHECKINGimports.Fixes are now always marked unsafe.
Pragma comments are excluded from line length calculation for I001.
The rule moves to the restriction category, changing how it is categorized for configuration and rule selection.
The preview default rules and categories are updated.
Rules can now be defined without codes.
The server can offer display-only fixes and marks safe fixes as preferred.
The delete-full-slice rule is now restricted to lists.
The existing exception now includes ctypes.LittleEndianStructure and related types.
Registers formatting capabilities dynamically to exclude TOML files.
Fixes that remove unknown separators are now marked unsafe.
Fixes are safe by default and unsafe only when comments are present.
Fixes for this rule are now marked unsafe.
The airflow3-incompatible-function-signature rule is stabilized and no longer in preview.
blind-except is suppressed when the exception is logged through logging methods other than critical, error, and exception.
The missing-copyright-notice rule is stabilized and no longer in preview.
The unnecessary-from-float rule is stabilized and no longer in preview.
The sorted-min-max rule is stabilized and no longer in preview.
Recognizes additional common gettext usage patterns, such as assigning gettext to builtins._.
Recognizes additional common gettext usage patterns, such as assigning gettext to builtins._.
Recognizes additional common gettext usage patterns, such as assigning gettext to builtins._.
The implicit-string-concatenation-in-collection-literal rule is stabilized and no longer in preview.
The log-exception-outside-except-handler rule is stabilized and no longer in preview.
The invalid-bool-return-type rule is stabilized and no longer in preview.
The too-many-positional-arguments rule is stabilized and no longer in preview.
The stop-iteration-return rule is stabilized and no longer in preview.
The none-not-at-end-of-union rule is stabilized and no longer in preview.
The access-annotations-from-class-dict rule is stabilized and no longer in preview.
The duplicate-entry-in-dunder-all rule is stabilized and no longer in preview.
Check output now shows fixes.
Ruff suppression comments now insert a space after the colon.
Recognizes typing_extensions.Text in addition to typing.Text.
Tooling 7
Warnings now include the rule name and code.
RUF039 and RUF055 now recognize
re.prefixmatch.Adds an autofix for PT020, allowing Ruff to automatically fix violations.
The flake8-use-pathlib rule now offers an autofix.
Pull diagnostics are now supported for notebook cells.
Rule codes in the statistics output are now hyperlinked.
The LSP now lints TOML files.
Fixes and other changes 66
Avoids false positives for calls with keyword arguments.
Avoids false positives for calls with keyword arguments.
Avoids false positives for calls with keyword arguments.
Updates LibCST-based fixes for Python 3.15.
Mentions stubs in the diagnostic message.
Avoids false positives for overloaded division.
Allows lazy imports to be used in deferred annotations.
Ruff now visits functional TypedDict keyword arguments correctly.
Ruff recognizes PEP-728 keywords on
TypedDictclasses.Detects
\Zinpytest.raises()match patterns.The automatic fix preserves operand order.
Detects nested
async withunder a synchronous parent.Ruff skips conversions when
TypeVarTupleorParamSpechave bounds or constraints.Ruff recognizes quoted types in
typing.TypeForm.Stops recommending deprecated
ByteStringaliases.Multiline fixes preserve required parentheses.
Stops defining
__cached__for Python 3.15.Corrects the diagnostic for the conflict between D211 and D203.
Allows alternate nested quotes inside format spec interpolations.
Gates the PLW0133 check for
ImportCycleErroron Python 3.15.Marks a fix unsafe when it would create a docstring.
Recognizes
sliceandfrozendictgenerics.Skips fixes for multi-member imports.
Stops recommending the removed
typing.no_type_check_decorator.ASYNC230 now recognizes
builtins.open.Fixes a panic on match subjects.
Unary plus is allowed in match patterns on Python 3.15.
PLW1514 now recognizes
builtins.open.Avoids emitting duplicate PT017 diagnostics.
Adds a display-only fix for
os.listdir.Ruff-specific suppressions no longer produce a
lint.externalhint.Prevents a fix loop between TID254 and TID255.
Unary expressions are validated when parsing.
Detects blocking generic HTTP requests.
Allows timezone-safe strptime chains.
Respects side effects in lambda defaults.
The rule is skipped when the open argument is a file descriptor.
The rule is skipped when the open argument is a file descriptor.
Fixes InvalidInstruction errors on Windows CPUs that do not support POPCNT.
The error message for mixed t-string and bytes syntax is aligned with CPython 3.14.
Syntax errors now detect parameters declared nonlocal.
The import-private-name rule now allows imports of os._exit.
Allows
continueinfinallyon Python 3.8.Makes the
np.chararrayautofix backwards-compatible.Fixes false positives and negatives involving the
%bformat character.Improves handling of concatenated strings.
Fixes a false positive with bools.
Fixes false positives and negatives involving the
%bformat character.Fixes false negatives on negative numbers.
Checks keyword arguments as well as other arguments.
Avoids false positives on singledispatch functions.
Marks
rangeas immutable.The fix NFKC-normalizes keyword names.
Section detection is skipped inside RST directive bodies.
Fixes indexing of excluded nested Ruff workspaces.
The fix parenthesizes
yieldarguments.Unknown enumeration values in LSP messages are handled gracefully.
Avoids a false positive when a variable is read in a
finallyclause.Fixes a false positive involving unpacked arguments.
Syntax error noise is reduced by swallowing dedents like indents.
The fixer skips changes when a defaulted TypeVar precedes a non-defaulted one.
Fixes a missing check on unrecognized early bound.
Resolves local string literal bindings to avoid more false positives.
Supports the recommended API from newer versions of PySNMP.
Supports the recommended API from newer versions of PySNMP.
Fixes a false positive involving a TypeVar default before Python 3.13.
ruff 0.15106 changes
Breaking changes 12
The pytest-fixture-autouse rule has been removed.
The parser now rejects _ as a match-pattern target.
The pydocstyle rule now prevents property docstrings from starting with verbs.
The parser now rejects __debug__ as a lambda parameter.
The flake8-pyi rule formerly named PYI033 is renamed to legacy-type-comment.
The parser now rejects multiple starred names in sequence patterns.
The parser now rejects parenthesized star imports.
The flake8-pyi rule now applies to Python files as well.
The parser now rejects starred comprehension targets.
The parser now rejects unparenthesized generator expressions in class bases.
The parser now rejects yield expressions after commas.
The rule no longer offers an autofix for
np.in1d.
New APIs and options 13
Adds a rule to replace
noqacomments withruff:ignore.Adds a rule to use human-readable names in
ruff:ignorecomments.Adds a rule to use human-readable names in configuration selectors.
Adds an option for adding ruff:ignore comments.
Adds --extend-exclude to ruff format.
Rule selectors can now use human-readable names.
Adds a rule that bans
pytestautouse fixtures.The command accepts rule names.
Implements the yield-in-context-manager-in-async-generator diagnostic, allowing Ruff to detect this pattern.
Adds the airflow-task-implicit-multiple-outputs rule.
Adds the incorrect-decorator-order rule.
Adds the fallible-context-manager rule.
Adds the too-many-try-statements rule.
Performance 12
Reserves capacity for builtin bindings.
Optimizes formatter text width and indentation.
Source files are created lazily for lint diagnostics.
Uses ArrayVec for qualified name segments.
Avoids allocating when parsing single string literals.
Avoids reallocating singleton call arguments.
Skips repeated-key checks for singleton dictionaries.
Drops excess capacity from statement suites during parsing.
Avoids redundant TokenValue drops in the lexer.
Uses ThinVec in the AST to shrink Stmt.
Reduces memory usage by dropping token-excess capacity and improves performance by approximating the initial tokens Vec size.
Avoids unnecessary parser lookahead for operators.
Behavior and default changes 14
Allows subclassing builtins in stub files.
Drops the tuple-comprehension preview behavior for C409.
Formatting comments no longer normalizes whitespace.
Skips overload-with-docstring in stub files.
Marks PYI061 fixes as unsafe in Python files.
Unknown rule selectors now emit a warning instead of an error.
Diagnostic links in the playground are now clickable.
LSP and playground diagnostics now use human-readable names.
The server renders subdiagnostics and secondary annotations as related information.
Severity is no longer displayed in output.
Python version comparisons are exempt from this rule.
Suppression comments can use human-readable rule names.
Automatically adds
from __future__ import annotationsfor this rule.Avoids fixes for ambiguous
argnamesandargvaluescombinations.
Tooling 8
Adds an autofix for E402.
Adds linting and fixes for use of deprecated abc decorators.
Suppression comments and code actions support human-readable names when hovered.
The playground now uses diagnostic tags.
CLI output now uses human-readable names.
Pytest style checks also cover
pytest_asynciofixtures.Automatically adds
from __future__ import annotationsfor this rule.Adds full support for PEP 798.
Fixes and other changes 47
Ignores mutable type updates in
redefined-loop-name.Fixes a false positive in
__all__.Marks the EXE004 fix as unsafe.
Refines detection of non-empty f-strings.
Fixes an autofix that incorrectly stripped + from comments.
Detects syntax errors in individual notebook cells.
Shebang handling in ruff:ignore comments now matches noqa shebang handling.
Ruff falls back to default settings when editor-only settings are invalid.
Fixes a panic when inserting text at a notebook cell boundary.
Updates fix suggestions for __floor__, __trunc__, __length_hint__, and __matmul__ variants.
Ruff crates are published to crates.io.
Ruff now detects mapping keys that are equivalent numeric values.
The parser now validates the default order of function type parameters.
Ruff now detects mapping keys equivalent to booleans.
Ruff now handles nested ruff:ignore comments.
Ruff now detects repeated signed and complex dictionary keys.
trio.as_safe_channelis recognized as a safe decorator.Clarifies the diagnostic message for single parameters.
The formatter preserves whitespace for Quarto cell option comments.
Fixes diagnostics when
ruff:enableorruff:disableappears whereruff:ignoreis expected.Fixes diagnostics when
ruff:enableorruff:disableappears whereruff:ignoreis expected.Suppressions respect diagnostic start and parent ranges, as well as trailing comments.
Handling of ignore comments within a disable/enable pair is fixed.
Preserves leading empty literals to avoid syntax errors.
No longer flags
ruff:ignorecomments as code.Fixes a conflict with RUF100 when
noqais on commented-out code.Avoids removing a
formatcall when doing so would change behavior.Avoids syntax errors from invalid character replacements in f-strings before Python 3.12; the fix also covers PLE2512, PLE2513, PLE2514, and PLE2515.
Narrows the diagnostic range and excludes cases without exception handlers.
Treats
yieldbeforebreakfrom a terminal loop as terminal.Avoids converting
formatcalls with more kinds of side effects.Returns a code action for resolve requests that contain no URL or no valid URL.
Reports duplicate imports in typing.TYPE_CHECKING blocks.
Treats function-scope bare annotations as locals, per PEP 526.
Fixes formatting of lambdas nested within f-strings.
Fixes how Ruff handles closing fences in Markdown.
Expands semantic syntax errors reported for invalid walruses.
Skips the rule for lambdas with positional-only parameters.
Treats generic frozenset annotations as immutable.
Fixes lambda formatting in interpolated string expressions.
Adds a recursion limit to the parser.
Avoids false positives in else clauses.
Marks the fix as unsafe when the first argument is a class attribute annotated as int.
Preserves f-string source verbatim in the fix.
Avoids strict behavior when future annotations are enabled.
Avoids strict behavior when future annotations are enabled.
Avoids strict behavior when future annotations are enabled.