273 KiB
Changelog
0.11.6
Preview features
- Avoid adding whitespace to the end of a docstring after an escaped quote (#17216)
- [
airflow] ExtractAIR311fromAIR301rules (AIR301,AIR311) (#17310, #17422)
Bug fixes
- Raise syntax error when
\is at end of file (#17409)
0.11.5
Preview features
- [
airflow] Add missingAIR302attribute check (#17115) - [
airflow] Expand module path check to individual symbols (AIR302) (#17278) - [
airflow] ExtractAIR312fromAIR302rules (AIR302,AIR312) (#17152) - [
airflow] Update oudatedAIR301,AIR302rules (#17123) - [syntax-errors] Async comprehension in sync comprehension (#17177)
- [syntax-errors] Check annotations in annotated assignments (#17283)
- [syntax-errors] Extend annotation checks to
await(#17282)
Bug fixes
- [
flake8-pie] Avoid false positive for multiple assignment withauto()(PIE796) (#17274)
Rule changes
- [
ruff] FixRUF100to detect unused file-levelnoqadirectives with specific codes (#17042) (#17061) - [
flake8-pytest-style] Avoid false positive for legacy form ofpytest.raises(PT011) (#17231)
Documentation
- Fix formatting of "See Style Guide" link (#17272)
0.11.4
Preview features
- [
ruff] Implementinvalid-rule-codeasRUF102(#17138) - [syntax-errors] Detect duplicate keys in
matchmapping patterns (#17129) - [syntax-errors] Detect duplicate attributes in
matchclass patterns (#17186) - [syntax-errors] Detect invalid syntax in annotations (#17101)
Bug fixes
- [syntax-errors] Fix multiple assignment error for class fields in
matchpatterns (#17184) - Don't skip visiting non-tuple slice in
typing.Annotatedsubscripts (#17201)
0.11.3
Preview features
- [
airflow] Add more autofixes forAIR302(#16876, #16977, #16976, #16965) - [
airflow] MoveAIR301toAIR002(#16978) - [
airflow] MoveAIR302toAIR301andAIR303toAIR302(#17151) - [
flake8-bandit] Markstrandlist[str]literals as trusted input (S603) (#17136) - [
ruff] Support slices inRUF005(#17078) - [syntax-errors] Start detecting compile-time syntax errors (#16106)
- [syntax-errors] Duplicate type parameter names (#16858)
- [syntax-errors] Irrefutable
casepattern before final case (#16905) - [syntax-errors] Multiple assignments in
casepattern (#16957) - [syntax-errors] Single starred assignment target (#17024)
- [syntax-errors] Starred expressions in
return,yield, andfor(#17134) - [syntax-errors] Store to or delete
__debug__(#16984)
Bug fixes
- Error instead of
panic!when running Ruff from a deleted directory (#16903) (#17054) - [syntax-errors] Fix false positive for parenthesized tuple index (#16948)
CLI
- Check
pyproject.tomlcorrectly when it is passed via stdin (#16971)
Configuration
- [
flake8-import-conventions] Add importnumpy.typing as nptto defaultflake8-import-conventions.aliases(#17133)
Documentation
- [
refurb] Document whyUserDict,UserList, andUserStringare preferred overdict,list, andstr(FURB189) (#16927)
0.11.2
Preview features
- [syntax-errors] Fix false-positive syntax errors emitted for annotations on variadic parameters before Python 3.11 (#16878)
0.11.1
Preview features
- [
airflow] Addchain,chain_linearandcross_downstreamforAIR302(#16647) - [syntax-errors] Improve error message and range for pre-PEP-614 decorator syntax errors (#16581)
- [syntax-errors] PEP 701 f-strings before Python 3.12 (#16543)
- [syntax-errors] Parenthesized context managers before Python 3.9 (#16523)
- [syntax-errors] Star annotations before Python 3.11 (#16545)
- [syntax-errors] Star expression in index before Python 3.11 (#16544)
- [syntax-errors] Unparenthesized assignment expressions in sets and indexes (#16404)
Bug fixes
- Server: Allow
FixAllaction in presence of version-specific syntax errors (#16848) - [
flake8-bandit] Allow raw strings insuspicious-mark-safe-usage(S308) #16702 (#16770) - [
refurb] Avoid panickingunwrapinverbose-decimal-constructor(FURB157) (#16777) - [
refurb] Fix starred expressions fix (FURB161) (#16550) - Fix
--statisticsreporting for unsafe fixes (#16756)
Rule changes
- [
flake8-executables] Allowuv runin shebang line forshebang-missing-python(EXE003) (#16849,#16855)
CLI
- Add
--exit-non-zero-on-format(#16009)
Documentation
- Update Ruff tutorial to avoid non-existent fix in
__init__.py(#16818) - [
flake8-gettext] Swapformat-andprintf-in-get-text-func-callexamples (INT002,INT003) (#16769)
0.11.0
This is a follow-up to release 0.10.0. Because of a mistake in the release process, the requires-python inference changes were not included in that release. Ruff 0.11.0 now includes this change as well as the stabilization of the preview behavior for PGH004.
Breaking changes
-
Changes to how the Python version is inferred when a
target-versionis not specified (#16319)In previous versions of Ruff, you could specify your Python version with:
- The
target-versionoption in aruff.tomlfile or the[tool.ruff]section of a pyproject.toml file. - The
project.requires-pythonfield in apyproject.tomlfile with a[tool.ruff]section.
These options worked well in most cases, and are still recommended for fine control of the Python version. However, because of the way Ruff discovers config files,
pyproject.tomlfiles without a[tool.ruff]section would be ignored, including therequires-pythonsetting. Ruff would then use the default Python version (3.9 as of this writing) instead, which is surprising when you've attempted to request another version.In v0.10, config discovery has been updated to address this issue:
- If Ruff finds a
ruff.tomlfile without atarget-version, it will check for apyproject.tomlfile in the same directory and respect itsrequires-pythonversion, even if it does not contain a[tool.ruff]section. - If Ruff finds a user-level configuration, the
requires-pythonfield of the closestpyproject.tomlin a parent directory will take precedence. - If there is no config file (
ruff.tomlorpyproject.tomlwith a[tool.ruff]section) in the directory of the file being checked, Ruff will search for the closestpyproject.tomlin the parent directories and use itsrequires-pythonsetting.
- The
Stabilization
The following behaviors have been stabilized:
blanket-noqa(PGH004): Also detect blanked file-level noqa comments (and not just line level comments).
Preview features
- [syntax-errors] Tuple unpacking in
forstatement iterator clause before Python 3.9 (#16558)
0.10.0
Check out the blog post for a migration guide and overview of the changes!
Breaking changes
See also, the "Remapped rules" section which may result in disabled rules.
-
Changes to how the Python version is inferred when a
target-versionis not specified (#16319)Because of a mistake in the release process, the
requires-pythoninference changes are not included in this release and instead shipped as part of 0.11.0. You can find a description of this change in the 0.11.0 section. -
Updated
TYPE_CHECKINGbehavior (#16669)Previously, Ruff only recognized typechecking blocks that tested the
typing.TYPE_CHECKINGsymbol. Now, Ruff recognizes any local variable namedTYPE_CHECKING. This release also removes support for the legacyif 0:andif False:typechecking checks. Use a localTYPE_CHECKINGvariable instead. -
More robust noqa parsing (#16483)
The syntax for both file-level and in-line suppression comments has been unified and made more robust to certain errors. In most cases, this will result in more suppression comments being read by Ruff, but there are a few instances where previously read comments will now log an error to the user instead. Please refer to the documentation on Error suppression for the full specification.
-
Avoid unnecessary parentheses around with statements with a single context manager and a trailing comment (#14005)
This change fixes a bug in the formatter where it introduced unnecessary parentheses around with statements with a single context manager and a trailing comment. This change may result in a change in formatting for some users.
-
Bump alpine default tag to 3.21 for derived Docker images (#16456)
Alpine 3.21 was released in Dec 2024 and is used in the official Alpine-based Python images. Now the ruff:alpine image will use 3.21 instead of 3.20 and ruff:alpine3.20 will no longer be updated.
Deprecated Rules
The following rules have been deprecated:
non-pep604-isinstance(UP038)suspicious-xmle-tree-usage(S320)
Remapped rules
The following rules have been remapped to new rule codes:
- [
unsafe-markup-use]:RUF035toS704
Stabilization
The following rules have been stabilized and are no longer in preview:
batched-without-explicit-strict(B911)unnecessary-dict-comprehension-for-iterable(C420)datetime-min-max(DTZ901)fast-api-unused-path-parameter(FAST003)root-logger-call(LOG015)len-test(PLC1802)shallow-copy-environ(PLW1507)os-listdir(PTH208)invalid-pathlib-with-suffix(PTH210)invalid-assert-message-literal-argument(RUF040)unnecessary-nested-literal(RUF041)unnecessary-cast-to-int(RUF046)map-int-version-parsing(RUF048)if-key-in-dict-del(RUF051)unsafe-markup-use(S704). This rule has also been renamed fromRUF035.split-static-string(SIM905)runtime-cast-value(TC006)unquoted-type-alias(TC007)non-pep646-unpack(UP044)
The following behaviors have been stabilized:
bad-staticmethod-argument(PLW0211)invalid-first-argument-name-for-class-method(N804):__new__methods are now no longer flagged byinvalid-first-argument-name-for-class-method(N804) but instead bybad-staticmethod-argument(PLW0211)bad-str-strip-call(PLE1310): The rule now applies to objects which are known to have typestrorbytes.custom-type-var-for-self(PYI019): More accurate detection of customTypeVarsreplaceable bySelf. The range of the diagnostic is now the full function header rather than just the return annotation.invalid-argument-name(N803): Ignore argument names of functions decorated withtyping.overrideinvalid-envvar-default(PLW1508): Detect default value arguments toos.environ.getwith invalid type.pytest-raises-with-multiple-statements(PT012)pytest-warns-with-multiple-statements(PT031): Allowforstatements with an empty body inpytest.raisesandpytest.warnswithstatements.redundant-open-modes(UP015): The diagnostic range is now the range of the redundant mode argument where it previously was the range of the entire open call. You may have to replace yournoqacomments when suppressingUP015.stdlib-module-shadowing(A005): Changes the default value oflint.flake8-builtins.strict-checkingfromtruetofalse.type-none-comparison(FURB169): Now also recognizestype(expr) is type(None)comparisons whereexprisn't a name expression.
The following fixes or improvements to fixes have been stabilized:
repeated-equality-comparison(PLR1714) (#16685)needless-bool(SIM103) (#16684)unused-private-type-var(PYI018) (#16682)
Server
- Remove logging output for
ruff.printDebugInformation(#16617)
Configuration
- [
flake8-builtins] Deprecate thebuiltins-prefixed options in favor of the unprefixed options (e.g.builtins-allowed-modulesis now deprecated in favor ofallowed-modules) (#16092)
Bug fixes
- [flake8-bandit] Fix mixed-case hash algorithm names (S324) (#16552)
CLI
- [ruff] Fix
last_tag/commits_since_last_tagforversioncommand (#16686)
0.9.10
Preview features
- [
ruff] Add new ruleRUF059: Unused unpacked assignment (#16449) - [
syntax-errors] Detect assignment expressions before Python 3.8 (#16383) - [
syntax-errors] Named expressions in decorators before Python 3.9 (#16386) - [
syntax-errors] Parenthesized keyword argument names after Python 3.8 (#16482) - [
syntax-errors] Positional-only parameters before Python 3.8 (#16481) - [
syntax-errors] Tuple unpacking inreturnandyieldbefore Python 3.8 (#16485) - [
syntax-errors] Type parameter defaults before Python 3.13 (#16447) - [
syntax-errors] Type parameter lists before Python 3.12 (#16479) - [
syntax-errors]except*before Python 3.11 (#16446) - [
syntax-errors]typestatements before Python 3.12 (#16478)
Bug fixes
- Escape template filenames in glob patterns in configuration (#16407)
- [
flake8-simplify] Exempt unittest context methods forSIM115rule (#16439) - Formatter: Fix syntax error location in notebooks (#16499)
- [
pyupgrade] Do not offer fix when at least one target isglobal/nonlocal(UP028) (#16451) - [
flake8-builtins] Ignore variables matching module attribute names (A001) (#16454) - [
pylint] Convertcodekeyword argument to a positional argument in fix for (PLR1722) (#16424)
CLI
- Move rule code from
descriptiontocheck_namein GitLab output serializer (#16437)
Documentation
- [
pydocstyle] Clarify thatD417only checks docstrings with an arguments section (#16494)
0.9.9
Preview features
- Fix caching of unsupported-syntax errors (#16425)
Bug fixes
- Only show unsupported-syntax errors in editors when preview mode is enabled (#16429)
0.9.8
Preview features
- Start detecting version-related syntax errors in the parser (#16090)
Rule changes
- [
pylint] Mark fix unsafe (PLW1507) (#16343) - [
pylint] Catchcase np.nan/case math.naninmatchstatements (PLW0177) (#16378) - [
ruff] Add more Pydantic models variants to the list of default copy semantics (RUF012) (#16291)
Server
- Avoid indexing the project if
configurationPreferenceiseditorOnly(#16381) - Avoid unnecessary info at non-trace server log level (#16389)
- Expand
ruff.configurationto allow inline config (#16296) - Notify users for invalid client settings (#16361)
Configuration
- Add
per-file-target-versionoption (#16257)
Bug fixes
- [
refurb] Do not consider docstring(s) (FURB156) (#16391) - [
flake8-self] Ignore attribute accesses on instance-like variables (SLF001) (#16149) - [
pylint] Fix false positives, add missing methods, and support positional-only parameters (PLE0302) (#16263) - [
flake8-pyi] MarkPYI030fix unsafe when comments are deleted (#16322)
Documentation
- Fix example for
S611(#16316) - Normalize inconsistent markdown headings in docstrings (#16364)
- Document MSRV policy (#16384)
0.9.7
Preview features
- Consider
__new__methods as special function type for enforcing class method or static method rules (#13305) - [
airflow] Improve the internal logic to differentiate deprecated symbols (AIR303) (#16013) - [
refurb] Manual timezone monkeypatching (FURB162) (#16113) - [
ruff] Implicit class variable in dataclass (RUF045) (#14349) - [
ruff] Skip singleton starred expressions forincorrectly-parenthesized-tuple-in-subscript(RUF031) (#16083) - [
refurb] Check for subclasses includes subscript expressions (FURB189) (#16155)
Rule changes
- [
flake8-debugger] Also flagsys.breakpointhookandsys.__breakpointhook__(T100) (#16191) - [
pycodestyle] Exemptsite.addsitedir(...)calls (E402) (#16251)
Formatter
- Fix unstable formatting of trailing end-of-line comments of parenthesized attribute values (#16187)
Server
- Fix handling of requests received after shutdown message (#16262)
- Ignore
source.organizeImports.ruffandsource.fixAll.ruffcode actions for a notebook cell (#16154) - Include document specific debug info for
ruff.printDebugInformation(#16215) - Update server to return the debug info as string with
ruff.printDebugInformation(#16214)
CLI
- Warn on invalid
noqaeven when there are no diagnostics (#16178) - Better error messages while loading configuration
extends (#15658)
Bug fixes
- [
flake8-comprehensions] Handle trailing comma inC403fix (#16110) - [
flake8-pyi] Avoid flaggingcustom-typevar-for-selfon metaclass methods (PYI019) (#16141) - [
pydocstyle] Handle arguments with the same names as sections (D417) (#16011) - [
pylint] Correct ordering of arguments in fix forif-stmt-min-max(PLR1730) (#16080) - [
pylint] Do not offer fix for raw strings (PLE251) (#16132) - [
pyupgrade] Do not upgrade functionalTypedDictswith private field names to the class-based syntax (UP013) (#16219) - [
pyupgrade] Handle micro version numbers correctly (UP036) (#16091) - [
pyupgrade] Unwrap unary expressions correctly (UP018) (#15919) - [
refurb] Correctly handle lengths of literal strings inslice-to-remove-prefix-or-suffix(FURB188) (#16237) - [
ruff] SkipRUF001diagnostics when visiting string type definitions (#16122)
Documentation
0.9.6
Preview features
- [
airflow] Addexternal_task.{ExternalTaskMarker, ExternalTaskSensor}forAIR302(#16014) - [
flake8-builtins] Make strict module name comparison optional (A005) (#15951) - [
flake8-pyi] Extend fix to Python <= 3.9 forredundant-none-literal(PYI061) (#16044) - [
pylint] Also report when the object isn't a literal (PLE1310) (#15985) - [
ruff] Implementindented-form-feed(RUF054) (#16049) - [
ruff] Skip type definitions formissing-f-string-syntax(RUF027) (#16054)
Rule changes
- [
flake8-annotations] Correct syntax fortyping.Unionin suggested return type fixes forANN20xrules (#16025) - [
flake8-builtins] Match upstream module name comparison (A005) (#16006) - [
flake8-comprehensions] Detect overshadowedlist/set/dict, ignore variadics and named expressions (C417) (#15955) - [
flake8-pie] Remove following comma correctly when the unpacked dictionary is empty (PIE800) (#16008) - [
flake8-simplify] Only triggerSIM401on known dictionaries (#15995) - [
pylint] Do not report calls when object type and argument type mismatch, remove custom escape handling logic (PLE1310) (#15984) - [
pyupgrade] Comments within parenthesized value ranges should not affect applicability (UP040) (#16027) - [
pyupgrade] Don't introduce invalid syntax when upgrading old-style type aliases with parenthesized multiline values (UP040) (#16026) - [
pyupgrade] Ensure we do not rename two type parameters to the same name (UP049) (#16038) - [
pyupgrade] [ruff] Don't apply renamings if the new name is shadowed in a scope of one of the references to the binding (UP049,RUF052) (#16032) - [
ruff] UpdateRUF009to behave similar toB008and ignore attributes with immutable types (#16048)
Server
- Root exclusions in the server to project root (#16043)
Bug fixes
- [
flake8-datetime] Ignore.replace()calls while looking for.astimezone(#16050) - [
flake8-type-checking] AvoidTC004false positive where the runtime definition is provided by__getattr__(#16052)
Documentation
0.9.5
Preview features
- Recognize all symbols named
TYPE_CHECKINGforin_type_checking_block(#15719) - [
flake8-comprehensions] Handle builtins at top of file correctly forunnecessary-dict-comprehension-for-iterable(C420) (#15837) - [
flake8-logging].exception()andexc_info=outside exception handlers (LOG004,LOG014) (#15799) - [
flake8-pyi] Fix incorrect behaviour ofcustom-typevar-return-typepreview-mode autofix iftypingwas already imported (PYI019) (#15853) - [
flake8-pyi] Fix more complex cases (PYI019) (#15821) - [
flake8-pyi] MakePYI019autofixable for.pyfiles in preview mode as well as stubs (#15889) - [
flake8-pyi] Remove type parameter correctly when it is the last (PYI019) (#15854) - [
pylint] Fix missing parens in unsafe fix forunnecessary-dunder-call(PLC2801) (#15762) - [
pyupgrade] Better messages and diagnostic range (UP015) (#15872) - [
pyupgrade] Rename private type parameters in PEP 695 generics (UP049) (#15862) - [
refurb] Also report non-name expressions (FURB169) (#15905) - [
refurb] Mark fix as unsafe if there are comments (FURB171) (#15832) - [
ruff] Classes with mixed type variable style (RUF053) (#15841) - [
airflow]BashOperatorhas been moved toairflow.providers.standard.operators.bash.BashOperator(AIR302) (#15922) - [
flake8-pyi] Add autofix for unused-private-type-var (PYI018) (#15999) - [
flake8-pyi] Significantly improve accuracy ofPYI019if preview mode is enabled (#15888)
Rule changes
- Preserve triple quotes and prefixes for strings (#15818)
- [
flake8-comprehensions] Skip whenTypeErrorpresent from too many (kw)args forC410,C411, andC418(#15838) - [
flake8-pyi] RenamePYI019and improve its diagnostic message (#15885) - [
pep8-naming] Ignore@overridemethods (N803) (#15954) - [
pyupgrade] Reuse replacement logic fromUP046andUP047to preserve more comments (UP040) (#15840) - [
ruff] Analyze deferred annotations before enforcingmutable-(data)class-defaultandfunction-call-in-dataclass-default-argument(RUF008,RUF009,RUF012) (#15921) - [
pycodestyle] Exemptsys.path += ...calls (E402) (#15980)
Configuration
- Config error only when
flake8-import-conventionsalias conflicts withisort.required-importsbound name (#15918) - Workaround Even Better TOML crash related to
allOf(#15992)
Bug fixes
- [
flake8-comprehensions] Unnecessarylistcomprehension (rewrite as asetcomprehension) (C403) - Handle extraneous parentheses around list comprehension (#15877) - [
flake8-comprehensions] Handle trailing comma in fixes forunnecessary-generator-list/set(C400,C401) (#15929) - [
flake8-pyi] Fix several correctness issues withcustom-type-var-return-type(PYI019) (#15851) - [
pep8-naming] Consider any number of leading underscore forN801(#15988) - [
pyflakes] Visit forward annotations inTypeAliasTypeas types (F401) (#15829) - [
pylint] Correct min/max auto-fix and suggestion for (PL1730) (#15930) - [
refurb] Handle unparenthesized tuples correctly (FURB122,FURB142) (#15953) - [
refurb] AvoidNone | Noneas well as better detection and fix (FURB168) (#15779)
Documentation
- Add deprecation warning for
ruff-lsprelated settings (#15850) - Docs (
linter.md): clarify that Python files are always searched for in subdirectories (#15882) - Fix a typo in
non_pep695_generic_class.rs(#15946) - Improve Docs: Pylint subcategories' codes (#15909)
- Remove non-existing
lint.extendIgnoreeditor setting (#15844) - Update black deviations (#15928)
- Mention
UP049inUP046andUP047, addSee alsosection toUP040(#15956) - Add instance variable examples to
RUF012(#15982) - Explain precedence for
ignoreandselectconfig (#15883)
0.9.4
Preview features
- [
airflow] Extend airflow context parameter check forBaseOperator.execute(AIR302) (#15713) - [
airflow] UpdateAIR302to check for deprecated context keys (#15144) - [
flake8-bandit] Permit suspicious imports within stub files (S4) (#15822) - [
pylint] Do not triggerPLR6201on empty collections (#15732) - [
refurb] Do not emit diagnostic when loop variables are used outside loop body (FURB122) (#15757) - [
ruff] Add support for morerepatterns (RUF055) (#15764) - [
ruff] Check for shadowedmapbefore suggesting fix (RUF058) (#15790) - [
ruff] Do not emit diagnostic when all arguments tozip()are variadic (RUF058) (#15744) - [
ruff] Parenthesize fix when argument spans multiple lines forunnecessary-round(RUF057) (#15703)
Rule changes
- Preserve quote style in generated code (#15726, #15778, #15794)
- [
flake8-bugbear] ExemptNewTypecalls where the original type is immutable (B008) (#15765) - [
pylint] Honor banned top-level imports byTID253inPLC0415. (#15628) - [
pyupgrade] Ignoreis_typeddictandTypedDictfordeprecated-import(UP035) (#15800)
CLI
- Fix formatter warning message for
flake8-quotesoption (#15788) - Implement tab autocomplete for
ruff config(#15603)
Bug fixes
- [
flake8-comprehensions] Do not emitunnecessary-mapdiagnostic when lambda has different arity (C417) (#15802) - [
flake8-comprehensions] Parenthesizesortedwhen needed forunnecessary-call-around-sorted(C413) (#15825) - [
pyupgrade] Handle end-of-line comments forquoted-annotation(UP037) (#15824)
Documentation
- Add missing config docstrings (#15803)
- Add references to
trio.run_processandanyio.run_process(#15761) - Use
uv init --libin tutorial (#15718)
0.9.3
Preview features
- [
airflow] Argumentfail_stopin DAG has been renamed asfail_fast(AIR302) (#15633) - [
airflow] ExtendAIR303with more symbols (#15611) - [
flake8-bandit] Report all references to suspicious functions (S3) (#15541) - [
flake8-pytest-style] Do not emit diagnostics for emptyforloops (PT012,PT031) (#15542) - [
flake8-simplify] Avoid double negations (SIM103) (#15562) - [
pyflakes] Fix infinite loop with unused local import in__init__.py(F401) (#15517) - [
pylint] Do not report methods with only oneEM101-compatibleraise(PLR6301) (#15507) - [
pylint] Implementredefined-slots-in-subclass(W0244) (#9640) - [
pyupgrade] Add rules to use PEP 695 generics in classes and functions (UP046,UP047) (#15565, #15659) - [
refurb] Implementfor-loop-writes(FURB122) (#10630) - [
ruff] Implementneedless-elseclause (RUF047) (#15051) - [
ruff] Implementstarmap-zip(RUF058) (#15483)
Rule changes
- [
flake8-bugbear] Do not raise error if keyword argument is present and target-python version is less or equals than 3.9 (B903) (#15549) - [
flake8-comprehensions] strip parentheses around generators inunnecessary-generator-set(C401) (#15553) - [
flake8-pytest-style] Rewrite references to.exception(PT027) (#15680) - [
flake8-simplify] Mark fixes as unsafe (SIM201,SIM202) (#15626) - [
flake8-type-checking] Fix some safe fixes being labeled unsafe (TC006,TC008) (#15638) - [
isort] Omit trailing whitespace inunsorted-imports(I001) (#15518) - [
pydoclint] Allow ignoring one line docstrings forDOCrules (#13302) - [
pyflakes] Apply redefinition fixes by source code order (F811) (#15575) - [
pyflakes] Avoid removing too many imports inredefined-while-unused(F811) (#15585) - [
pyflakes] Group redefinition fixes by source statement (F811) (#15574) - [
pylint] Include name of base class in message forredefined-slots-in-subclass(W0244) (#15559) - [
ruff] Update fix forRUF055to usevar == value(#15605)
Formatter
- Fix bracket spacing for single-element tuples in f-string expressions (#15537)
- Fix unstable f-string formatting for expressions containing a trailing comma (#15545)
Performance
- Avoid quadratic membership check in import fixes (#15576)
Server
- Allow
unsafe-fixessettings for code actions (#15666)
Bug fixes
- [
flake8-bandit] Add missing single-line/dotall regex flag (S608) (#15654) - [
flake8-import-conventions] Fix infinite loop betweenICN001andI002(ICN001) (#15480) - [
flake8-simplify] Do not emit diagnostics for expressions inside string type annotations (SIM222,SIM223) (#15405) - [
pyflakes] Treat arguments passed to thedefault=parameter ofTypeVaras type expressions (F821) (#15679) - [
pyupgrade] Avoid syntax error when the iterable is a non-parenthesized tuple (UP028) (#15543) - [
ruff] ExemptNewTypecalls where the original type is immutable (RUF009) (#15588) - Preserve raw string prefix and escapes in all codegen fixes (#15694)
Documentation
- Generate documentation redirects for lowercase rule codes (#15564)
TRY300: Add some extra notes on not catching exceptions you didn't expect (#15036)
0.9.2
Preview features
- [
airflow] Fix typo "security_managr" to "security_manager" (AIR303) (#15463) - [
airflow] extend and fix AIR302 rules (#15525) - [
fastapi] Handle parameters withDependscorrectly (FAST003) (#15364) - [
flake8-pytest-style] Implement pytest.warns diagnostics (PT029,PT030,PT031) (#15444) - [
flake8-pytest-style] Test function parameters with default arguments (PT028) (#15449) - [
flake8-type-checking] Avoid false positives for|inTC008(#15201)
Rule changes
- [
flake8-todos] Allow VSCode GitHub PR extension style links inmissing-todo-link(TD003) (#15519) - [
pyflakes] Show syntax error message forF722(#15523)
Formatter
- Fix curly bracket spacing around f-string expressions containing curly braces (#15471)
- Fix joining of f-strings with different quotes when using quote style
Preserve(#15524)
Server
- Avoid indexing the same workspace multiple times (#15495)
- Display context for
ruff.configurationerrors (#15452)
Configuration
- Remove
flattento improve deserialization error messages (#15414)
Bug fixes
- Parse triple-quoted string annotations as if parenthesized (#15387)
- [
fastapi] UpdateAnnotatedfixes (FAST002) (#15462) - [
flake8-bandit] Check forbuiltinsinstead ofbuiltin(S102,PTH123) (#15443) - [
flake8-pathlib] Fix--selectforos-path-dirname(PTH120) (#15446) - [
ruff] Fix false positive on global keyword (RUF052) (#15235)
0.9.1
Preview features
- [
pycodestyle] Runtoo-many-newlines-at-end-of-fileon each cell in notebooks (W391) (#15308) - [
ruff] Omit diagnostic for shadowed private function parameters inused-dummy-variable(RUF052) (#15376)
Rule changes
- [
flake8-bugbear] Improveassert-raises-exceptionmessage (B017) (#15389)
Formatter
- Preserve trailing end-of line comments for the last string literal in implicitly concatenated strings (#15378)
Server
- Fix a bug where the server and client notebooks were out of sync after reordering cells (#15398)
Bug fixes
- [
flake8-pie] Correctly remove wrapping parentheses (PIE800) (#15394) - [
pyupgrade] Handle comments and multiline expressions correctly (UP037) (#15337)
0.9.0
Check out the blog post for a migration guide and overview of the changes!
Breaking changes
Ruff now formats your code according to the 2025 style guide. As a result, your code might now get formatted differently. See the formatter section for a detailed list of changes.
This release doesn’t remove or remap any existing stable rules.
Stabilization
The following rules have been stabilized and are no longer in preview:
stdlib-module-shadowing(A005). This rule has also been renamed: previously, it was calledbuiltin-module-shadowing.builtin-lambda-argument-shadowing(A006)slice-to-remove-prefix-or-suffix(FURB188)boolean-chained-comparison(PLR1716)decimal-from-float-literal(RUF032)post-init-default(RUF033)useless-if-else(RUF034)
The following behaviors have been stabilized:
pytest-parametrize-names-wrong-type(PT006): Detectpytest.parametrizecalls outside decorators and calls with keyword arguments.module-import-not-at-top-of-file(E402): Ignorepytest.importorskipcalls between import statements.mutable-dataclass-default(RUF008) andfunction-call-in-dataclass-default-argument(RUF009): Add support forattrs.bad-version-info-comparison(PYI006): Extend the rule to check non-stub files.
The following fixes or improvements to fixes have been stabilized:
redundant-numeric-union(PYI041)duplicate-union-members(PYI016)
Formatter
This release introduces the new 2025 stable style (#13371), stabilizing the following changes:
- Format expressions in f-string elements (#7594)
- Alternate quotes for strings inside f-strings (#13860)
- Preserve the casing of hex codes in f-string debug expressions (#14766)
- Choose the quote style for each string literal in an implicitly concatenated f-string rather than for the entire string (#13539)
- Automatically join an implicitly concatenated string into a single string literal if it fits on a single line (#9457)
- Remove the
ISC001incompatibility warning (#15123) - Prefer parenthesizing the
assertmessage over breaking the assertion expression (#9457) - Automatically parenthesize over-long
ifguards inmatchcaseclauses (#13513) - More consistent formatting for
matchcasepatterns (#6933) - Avoid unnecessary parentheses around return type annotations (#13381)
- Keep the opening parentheses on the same line as the
ifkeyword for comprehensions where the condition has a leading comment (#12282) - More consistent formatting for
withstatements with a single context manager for Python 3.8 or older (#10276) - Correctly calculate the line-width for code blocks in docstrings when using
max-doc-code-line-length = "dynamic"(#13523)
Preview features
- [
flake8-bugbear] Implementclass-as-data-structure(B903) (#9601) - [
flake8-type-checking] Applyquoted-type-aliasmore eagerly inTYPE_CHECKINGblocks and ignore it in stubs (TC008) (#15180) - [
pylint] Ignoreeq-without-hashin stub files (PLW1641) (#15310) - [
pyupgrade] SplitUP007into two individual rules:UP007forUnionandUP045forOptional(UP007,UP045) (#15313) - [
ruff] New rule that detects classes that are both an enum and adataclass(RUF049) (#15299) - [
ruff] RecodeRUF025toRUF037(RUF037) (#15258)
Rule changes
- [
flake8-builtins] Ignorestdlib-module-shadowingin stub files(A005) (#15350) - [
flake8-return] Add support for functions returningtyping.Never(RET503) (#15298)
Server
- Improve the observability by removing the need for the "trace" value to turn on or off logging. The server logging is solely controlled using the
logLevelserver setting which defaults toinfo. This addresses the issue where users were notified about an error and told to consult the log, but it didn’t contain any messages. (#15232) - Ignore diagnostics from other sources for code action requests (#15373)
CLI
- Improve the error message for
--config key=valuewhen thekeyis for a table and it’s a simplevalue
Bug fixes
- [
eradicate] Ignore metadata blocks directly followed by normal blocks (ERA001) (#15330) - [
flake8-django] Recognize other magic methods (DJ012) (#15365) - [
pycodestyle] Avoid false positives related to type aliases (E252) (#15356) - [
pydocstyle] Avoid treating newline-separated sections as sub-sections (D405) (#15311) - [
pyflakes] Remove call when removing final argument fromformat(F523) (#15309) - [
refurb] Mark fix as unsafe when the right-hand side is a string (FURB171) (#15273) - [
ruff] Treat)as a regex metacharacter (RUF043,RUF055) (#15318) - [
ruff] Parenthesize theint-call argument when removing theintcall would change semantics (RUF046) (#15277)
0.8.6
Preview features
- [
format]: Preserve multiline implicit concatenated strings in docstring positions (#15126) - [
ruff] Add rule to detect empty literal in deque call (RUF025) (#15104) - [
ruff] Avoid reporting whenndigitsis possibly negative (RUF057) (#15234)
Rule changes
- [
flake8-todos] remove issue code length restriction (TD003) (#15175) - [
pyflakes] Ignore errors in@no_type_checkstring annotations (F722,F821) (#15215)
CLI
- Show errors for attempted fixes only when passed
--verbose(#15237)
Bug fixes
- [
ruff] Avoid syntax error when removing int over multiple lines (RUF046) (#15230) - [
pyupgrade] Revert "Add all PEP-585 names toUP006rule" (#15250)
0.8.5
Preview features
- [
airflow] Extend names moved from core to provider (AIR303) (#15145, #15159, #15196, #15216) - [
airflow] Extend rule to check class attributes, methods, arguments (AIR302) (#15054, #15083) - [
fastapi] UpdateFAST002to check keyword-only arguments (#15119) - [
flake8-type-checking] DisableTC006andTC007in stub files (#15179) - [
pylint] Detect nested methods correctly (PLW1641) (#15032) - [
ruff] Detect more strict-integer expressions (RUF046) (#14833) - [
ruff] Implementfalsy-dict-get-fallback(RUF056) (#15160) - [
ruff] Implementunnecessary-round(RUF057) (#14828)
Rule changes
- Visit PEP 764 inline
TypedDictkeys as non-type-expressions (#15073) - [
flake8-comprehensions] SkipC416if comprehension contains unpacking (#14909) - [
flake8-pie] Allowcast(SomeType, ...)(PIE796) (#15141) - [
flake8-simplify] More precise inference for dictionaries (SIM300) (#15164) - [
flake8-use-pathlib] Catch redundant joins inPTH201and avoid syntax errors (#15177) - [
pycodestyle] Preserve original value format (E731) (#15097) - [
pydocstyle] Split on first whitespace character (D403) (#15082) - [
pyupgrade] Add all PEP-585 names toUP006rule (#5454)
Configuration
- [
flake8-type-checking] Improve flexibility ofruntime-evaluated-decorators(#15204) - [
pydocstyle] Add setting to ignore missing documentation for*argsand**kwargsparameters (D417) (#15210) - [
ruff] Add an allowlist forunsafe-markup-use(RUF035) (#15076)
Bug fixes
- Fix type subscript on older python versions (#15090)
- Use
TypeCheckerfor detectingfastapiroutes (#15093) - [
pycodestyle] Avoid false positives and negatives related to type parameter default syntax (E225,E251) (#15214)
Documentation
- Fix incorrect doc in
shebang-not-executable(EXE001) and add git+windows solution to executable bit (#15208) - Rename rules currently not conforming to naming convention (#15102)
0.8.4
Preview features
- [
airflow] ExtendAIR302with additional functions and classes (#15015) - [
airflow] Implementmoved-to-provider-in-3for modules that has been moved to Airflow providers (AIR303) (#14764) - [
flake8-use-pathlib] Extend check for invalid path suffix to include the case"."(PTH210) (#14902) - [
perflint] Fix panic inPERF401when list variable is after theforloop (#14971) - [
perflint] Simplify finding the loop target inPERF401(#15025) - [
pylint] Preserve original value format (PLR6104) (#14978) - [
ruff] Avoid false positives forRUF027for typing context bindings (#15037) - [
ruff] Check for ambiguous pattern passed topytest.raises()(RUF043) (#14966)
Rule changes
- [
flake8-bandit] CheckS105for annotated assignment (#15059) - [
flake8-pyi] More autofixes forredundant-none-literal(PYI061) (#14872) - [
pydocstyle] Skip leading whitespace forD403(#14963) - [
ruff] SkipSQLModelbase classes formutable-class-default(RUF012) (#14949)
Bug
- [
perflint] Parenthesize walrus expressions in autofix formanual-list-comprehension(PERF401) (#15050)
Server
- Check diagnostic refresh support from client capability which enables dynamic configuration for various editors (#15014)
0.8.3
Preview features
- Fix fstring formatting removing overlong implicit concatenated string in expression part (#14811)
- [
airflow] Add fix to remove deprecated keyword arguments (AIR302) (#14887) - [
airflow]: Extend rule to include deprecated names for Airflow 3.0 (AIR302) (#14765 and #14804) - [
flake8-bugbear] Improve error messages forexcept*(B025,B029,B030,B904) (#14815) - [
flake8-bugbear]itertools.batched()without explicitstrict(B911) (#14408) - [
flake8-use-pathlib] Dotless suffix passed toPath.with_suffix()(PTH210) (#14779) - [
pylint] Include parentheses and multiple comparators in check forboolean-chained-comparison(PLR1716) (#14781) - [
ruff] Do not simplifyround()calls (RUF046) (#14832) - [
ruff] Don't emitused-dummy-variableon function parameters (RUF052) (#14818) - [
ruff] Implementif-key-in-dict-del(RUF051) (#14553) - [
ruff] Mark autofix forRUF052as always unsafe (#14824) - [
ruff] Teach autofix forused-dummy-variableabout TypeVars etc. (RUF052) (#14819)
Rule changes
- [
flake8-bugbear] Offer unsafe autofix forno-explicit-stacklevel(B028) (#14829) - [
flake8-pyi] Skip all type definitions instring-or-bytes-too-long(PYI053) (#14797) - [
pyupgrade] Do not report when a UTF-8 comment is followed by a non-UTF-8 one (UP009) (#14728) - [
pyupgrade] Mark fixes forconvert-typed-dict-functional-to-classandconvert-named-tuple-functional-to-classas unsafe if they will remove comments (UP013,UP014) (#14842)
Bug fixes
- Raise syntax error for mixing
exceptandexcept*(#14895) - [
flake8-bugbear] FixB028to allowstacklevelto be explicitly assigned as a positional argument (#14868) - [
flake8-bugbear] SkipB028ifwarnings.warnis called with*argsor**kwargs(#14870) - [
flake8-comprehensions] Skip iterables with named expressions inunnecessary-map(C417) (#14827) - [
flake8-pyi] Also removeselfandcls's annotation (PYI034) (#14801) - [
flake8-pytest-style] Fixpytest-parametrize-names-wrong-type(PT006) to edit bothargnamesandargvaluesif both of them are single-element tuples/lists (#14699) - [
perflint] Improve autofix forPERF401(#14369) - [
pylint] FixPLW1508false positive for default string created via a mult operation (#14841)
0.8.2
Preview features
- [
airflow] Avoid deprecated values (AIR302) (#14582) - [
airflow] Extend removed names forAIR302(#14734) - [
ruff] Extendunnecessary-regular-expressionto non-literal strings (RUF055) (#14679) - [
ruff] Implementused-dummy-variable(RUF052) (#14611) - [
ruff] Implementunnecessary-cast-to-int(RUF046) (#14697)
Rule changes
- [
airflow] CheckAIR001from builtin or providersoperatorsmodule (#14631) - [
flake8-pytest-style] Remove@inpytest.mark.parametrizerule messages (#14770) - [
pandas-vet] Skip rules if thepandamodule hasn't been seen (#14671) - [
pylint] Fix false negatives forasciiandsortedinlen-as-condition(PLC1802) (#14692) - [
refurb] Guardhashlibimports and markhashlib-digest-hexfix as safe (FURB181) (#14694)
Configuration
- [
flake8-import-conventions] Improve syntax check for aliases supplied in configuration forunconventional-import-alias(ICN001) (#14745)
Bug fixes
- Revert: [pyflakes] Avoid false positives in
@no_type_checkcontexts (F821,F722) (#14615) (#14726) - [
pep8-naming] Avoid false positive forclass Bar(type(foo))(N804) (#14683) - [
pycodestyle] Handle f-strings properly forinvalid-escape-sequence(W605) (#14748) - [
pylint] Ignore@overloadinPLR0904(#14730) - [
refurb] Handle non-finite decimals inverbose-decimal-constructor(FURB157) (#14596) - [
ruff] Avoid emittingassignment-in-assertwhen all references to the assigned variable are themselves insideasserts (RUF018) (#14661)
Documentation
- Improve docs for
flake8-use-pathlibrules (#14741) - Improve error messages and docs for
flake8-comprehensionsrules (#14729) - [
flake8-type-checking] ExpandsTC006docs to better explain itself (#14749)
0.8.1
Preview features
- Formatter: Avoid invalid syntax for format-spec with quotes for all Python versions (#14625)
- Formatter: Consider quotes inside format-specs when choosing the quotes for an f-string (#14493)
- Formatter: Do not consider f-strings with escaped newlines as multiline (#14624)
- Formatter: Fix f-string formatting in assignment statement (#14454)
- Formatter: Fix unnecessary space around power operator (
**) in overlong f-string expressions (#14489) - [
airflow] Avoid implicitscheduleargument toDAGand@dag(AIR301) (#14581) - [
flake8-builtins] Exempt private built-in modules (A005) (#14505) - [
flake8-pytest-style] Fixpytest.mark.parametrizerules to check calls instead of decorators (#14515) - [
flake8-type-checking] Implementruntime-cast-value(TC006) (#14511) - [
flake8-type-checking] Implementunquoted-type-alias(TC007) andquoted-type-alias(TC008) (#12927) - [
flake8-use-pathlib] RecommendPath.iterdir()overos.listdir()(PTH208) (#14509) - [
pylint] Extendinvalid-envvar-defaultto detectos.environ.get(PLW1508) (#14512) - [
pylint] Implementlen-test(PLC1802) (#14309) - [
refurb] Fix bug where methods defined using lambdas were flagged byFURB118(#14639) - [
ruff] Auto-addrprefix when string has no backslashes forunraw-re-pattern(RUF039) (#14536) - [
ruff] Implementinvalid-assert-message-literal-argument(RUF040) (#14488) - [
ruff] Implementunnecessary-nested-literal(RUF041) (#14323) - [
ruff] Implementunnecessary-regular-expression(RUF055) (#14659)
Rule changes
- Ignore more rules for stub files (#14541)
- [
pep8-naming] Eliminate false positives for single-letter names (N811,N814) (#14584) - [
pyflakes] Avoid false positives in@no_type_checkcontexts (F821,F722) (#14615) - [
ruff] Detect redirected-noqa in file-level comments (RUF101) (#14635) - [
ruff] Mark fixes forunsorted-dunder-allandunsorted-dunder-slotsas unsafe when there are complex comments in the sequence (RUF022,RUF023) (#14560)
Bug fixes
- Avoid fixing code to
None | Noneforredundant-none-literal(PYI061) andnever-union(RUF020) (#14583, #14589) - [
flake8-bugbear] Fixmutable-contextvar-defaultto resolve annotated function calls properly (B039) (#14532) - [
flake8-pyi,ruff] Fix traversal of nested literals and unions (PYI016,PYI051,PYI055,PYI062,RUF041) (#14641) - [
flake8-pyi] Avoid rewriting invalid type expressions inunnecessary-type-union(PYI055) (#14660) - [
flake8-type-checking] Avoid syntax errors and type checking problem for quoted annotations autofix (TC003,TC006) (#14634) - [
pylint] Do not wrap function calls in parentheses in the fix for unnecessary-dunder-call (PLC2801) (#14601) - [
ruff] Handleattrs'sauto_attribscorrectly (RUF009) (#14520)
0.8.0
Check out the blog post for a migration guide and overview of the changes!
Breaking changes
See also, the "Remapped rules" section which may result in disabled rules.
-
Default to Python 3.9
Ruff now defaults to Python 3.9 instead of 3.8 if no explicit Python version is configured using
ruff.target-versionorproject.requires-python(#13896) -
Changed location of
pydoclintdiagnosticspydoclintdiagnostics now point to the first-line of the problematic docstring. Previously, this was not the case.If you've opted into these preview rules but have them suppressed using
noqacomments in some places, this change may mean that you need to move thenoqasuppression comments. Most users should be unaffected by this change. -
Use XDG (i.e.
~/.local/bin) instead of the Cargo home directory in the standalone installerPreviously, Ruff's installer used
$CARGO_HOMEor~/.cargo/binfor its target install directory. Now, Ruff will be installed into$XDG_BIN_HOME,$XDG_DATA_HOME/../bin, or~/.local/bin(in that order).This change is only relevant to users of the standalone Ruff installer (using the shell or PowerShell script). If you installed Ruff using uv or pip, you should be unaffected.
-
Changes to the line width calculation
Ruff now uses a new version of the unicode-width Rust crate to calculate the line width. In very rare cases, this may lead to lines containing Unicode characters being reformatted, or being considered too long when they were not before (
E501).
Removed Rules
The following deprecated rules have been removed:
missing-type-self(ANN101)missing-type-cls(ANN102)syntax-error(E999)pytest-missing-fixture-name-underscore(PT004)pytest-incorrect-fixture-name-underscore(PT005)unpacked-list-comprehension(UP027)
Remapped rules
The following rules have been remapped to new rule codes:
flake8-type-checking:TCHtoTC
Stabilization
The following rules have been stabilized and are no longer in preview:
builtin-import-shadowing(A004)mutable-contextvar-default(B039)fast-api-redundant-response-model(FAST001)fast-api-non-annotated-dependency(FAST002)dict-index-missing-items(PLC0206)pep484-style-positional-only-parameter(PYI063)redundant-final-literal(PYI064)bad-version-info-order(PYI066)parenthesize-chained-operators(RUF021)unsorted-dunder-all(RUF022)unsorted-dunder-slots(RUF023)assert-with-print-message(RUF030)unnecessary-default-type-args(UP043)
The following behaviors have been stabilized:
ambiguous-variable-name(E741): Violations in stub files are now ignored. Stub authors typically don't control variable names.printf-string-formatting(UP031): Report allprintf-like usages even if no autofix is available
The following fixes have been stabilized:
zip-instead-of-pairwise(RUF007)
Preview features
- [
flake8-datetimez] Exemptmin.time()andmax.time()(DTZ901) (#14394) - [
flake8-pie] Mark fix as unsafe if the following statement is a string literal (PIE790) (#14393) - [
flake8-pyi] New ruleredundant-none-literal(PYI061) (#14316) - [
flake8-pyi] Add autofix forredundant-numeric-union(PYI041) (#14273) - [
ruff] New rulemap-int-version-parsing(RUF048) (#14373) - [
ruff] New ruleredundant-bool-literal(RUF038) (#14319) - [
ruff] New ruleunraw-re-pattern(RUF039) (#14446) - [
pycodestyle] Exemptpytest.importorskip()calls (E402) (#14474) - [
pylint] Autofix suggests using sets when possible (PLR1714) (#14372)
Rule changes
invalid-pyproject-toml(RUF200): Updated to reflect the provisionally accepted PEP 639.- [
flake8-pyi] Avoid panic in unfixable case (PYI041) (#14402) - [
flake8-type-checking] Correctly handle quotes in subscript expression when generating an autofix (#14371) - [
pylint] Suggest correct autofix for__contains__(PLC2801) (#14424)
Configuration
- Ruff now emits a warning instead of an error when a configuration
ignores a rule that has been removed (#14435) - Ruff now validates that
lint.flake8-import-conventions.aliasesonly uses valid module names and aliases (#14477)
0.7.4
Preview features
- [
flake8-datetimez] Detect usages ofdatetime.max/datetime.min(DTZ901) (#14288) - [
flake8-logging] Implementroot-logger-calls(LOG015) (#14302) - [
flake8-no-pep420] Detect empty implicit namespace packages (INP001) (#14236) - [
flake8-pyi] Add "replace withSelf" fix (PYI019) (#14238) - [
perflint] Implement quick-fix formanual-list-comprehension(PERF401) (#13919) - [
pylint] Implementshallow-copy-environ(W1507) (#14241) - [
ruff] Implementnone-not-at-end-of-union(RUF036) (#14314) - [
ruff] Implementationunsafe-markup-callfromflake8-markupsafeplugin (RUF035) (#14224) - [
ruff] Report problems forattrsdataclasses (RUF008,RUF009) (#14327)
Rule changes
- [
flake8-boolean-trap] Exclude dunder methods that define operators (FBT001) (#14203) - [
flake8-pyi] Add "replace withSelf" fix (PYI034) (#14217) - [
flake8-pyi] Always autofixduplicate-union-members(PYI016) (#14270) - [
flake8-pyi] Improve autofix for nested and mixed type unions forunnecessary-type-union(PYI055) (#14272) - [
flake8-pyi] Mark fix as unsafe when type annotation contains comments forduplicate-literal-member(PYI062) (#14268)
Server
- Use the current working directory to resolve settings from
ruff.configuration(#14352)
Bug fixes
- Avoid conflicts between
PLC014(useless-import-alias) andI002(missing-required-import) by consideringlint.isort.required-importsforPLC014(#14287) - [
flake8-type-checking] Skip quoting annotation if it becomes invalid syntax (TCH001) - [
flake8-pyi] Avoid usingtyping.Selfin stub files pre-Python 3.11 (PYI034) (#14230) - [
flake8-pytest-style] Flagpytest.raisescall with keyword argumentexpected_exception(PT011) (#14298) - [
flake8-simplify] Infer "unknown" truthiness for literal iterables whose items are all unpacks (SIM222) (#14263) - [
flake8-type-checking] Fix false positives fortyping.Annotated(TCH001) (#14311) - [
pylint] Allowawaitat the top-level scope of a notebook (PLE1142) (#14225) - [
pylint] Fix miscellaneous issues inawait-outside-asyncdetection (PLE1142) (#14218) - [
pyupgrade] Avoid applying PEP 646 rewrites in invalid contexts (UP044) (#14234) - [
pyupgrade] Detect permutations in redundant open modes (UP015) (#14255) - [
refurb] Avoid triggeringhardcoded-string-charsetfor reordered sets (FURB156) (#14233) - [
refurb] Further special cases added toverbose-decimal-constructor(FURB157) (#14216) - [
refurb] UseUserStringinstead of non-existentUserStr(FURB189) (#14209) - [
ruff] Avoid treating lowercase letters as# noqacodes (RUF100) (#14229) - [
ruff] Do not report whenOptionalhas no type arguments (RUF013) (#14181)
Documentation
- Add "Notebook behavior" section for
F704,PLE1142(#14266) - Document comment policy around fix safety (#14300)
0.7.3
Preview features
- Formatter: Disallow single-line implicit concatenated strings (#13928)
- [
flake8-pyi] Include all Python file types forPYI006andPYI066(#14059) - [
flake8-simplify] Implementsplit-of-static-string(SIM905) (#14008) - [
refurb] Implementsubclass-builtin(FURB189) (#14105) - [
ruff] Improve diagnostic messages and docs (RUF031,RUF032,RUF034) (#14068)
Rule changes
- Detect items that hash to same value in duplicate sets (
B033,PLC0208) (#14064) - [
eradicate] Better detection of IntelliJ language injection comments (ERA001) (#14094) - [
flake8-pyi] Add autofix fordocstring-in-stub(PYI021) (#14150) - [
flake8-pyi] Updateduplicate-literal-member(PYI062) to alawys provide an autofix (#14188) - [
pyflakes] Detect items that hash to same value in duplicate dictionaries (F601) (#14065) - [
ruff] Fix false positive for decorators (RUF028) (#14061)
Bug fixes
- Avoid parsing joint rule codes as distinct codes in
# noqa(#12809) - [
eradicate] ignore# language=in commented-out-code rule (ERA001) (#14069) - [
flake8-bugbear] - do not runmutable-argument-defaulton stubs (B006) (#14058) - [
flake8-builtins] Skip lambda expressions inbuiltin-argument-shadowing (A002)(#14144) - [
flake8-comprehension] Also remove trailing comma while fixingC409andC419(#14097) - [
flake8-simplify] Allowopenwithout context manager inreturnstatement (SIM115) (#14066) - [
pylint] Respect hash-equivalent literals initeration-over-set(PLC0208) (#14063) - [
pylint] Update known dunder methods for Python 3.13 (PLW3201) (#14146) - [
pyupgrade] - ignore kwarg unpacking forUP044(#14053) - [
refurb] Parse more exotic decimal strings inverbose-decimal-constructor(FURB157) (#14098)
Documentation
- Add links to missing related options within rule documentations (#13971)
- Add rule short code to mkdocs tags to allow searching via rule codes (#14040)
0.7.2
Preview features
- Fix formatting of single with-item with trailing comment (#14005)
- [
pyupgrade] Add PEP 646Unpackconversion to*with fix (UP044) (#13988)
Rule changes
- Regenerate
known_stdlibs.rswith stdlibs 2024.10.25 (#13963) - [
flake8-no-pep420] Skip namespace package enforcement for PEP 723 scripts (INP001) (#13974)
Server
- Fix server panic when undoing an edit (#14010)
Bug fixes
- Fix issues in discovering ruff in pip build environments (#13881)
- [
flake8-type-checking] Fix false positive forsingledispatchmethod(TCH003) (#13941) - [
flake8-type-checking] Treat return type ofsingledispatchas runtime-required (TCH003) (#13957)
Documentation
- [
flake8-simplify] Include caveats of enablingif-else-block-instead-of-if-exp(SIM108) (#14019)
0.7.1
Preview features
- Fix
E221andE222to flag missing or extra whitespace around==operator (#13890) - Formatter: Alternate quotes for strings inside f-strings in preview (#13860)
- Formatter: Join implicit concatenated strings when they fit on a line (#13663)
- [
pylint] Restrictiteration-over-setto only work on sets of literals (PLC0208) (#13731)
Rule changes
- [
flake8-type-checking] Support auto-quoting when annotations contain quotes (#11811)
Server
- Avoid indexing the workspace for single-file mode (#13770)
Bug fixes
- Make
ARG002compatible withEM101when raisingNotImplementedError(#13714)
Other changes
- Introduce more Docker tags for Ruff (similar to uv) (#13274)
0.7.0
Check out the blog post for a migration guide and overview of the changes!
Breaking changes
- The pytest rules
PT001andPT023now default to omitting the decorator parentheses when there are no arguments (#12838, #13292). This was a change that we attempted to make in Ruff v0.6.0, but only partially made due to an error on our part. See the blog post for more details. - The
useless-try-exceptrule (in ourtryceratopscategory) has been recoded fromTRY302toTRY203(#13502). This ensures Ruff's code is consistent with the same rule in thetryceratopslinter. - The
lint.allow-unused-importssetting has been removed (#13677). Uselint.pyflakes.allow-unused-importsinstead.
Formatter preview style
- Normalize implicit concatenated f-string quotes per part (#13539)
Preview linter features
- [
refurb] implementhardcoded-string-charset(FURB156) (#13530) - [
refurb] Count codepoints not bytes forslice-to-remove-prefix-or-suffix (FURB188)(#13631)
Rule changes
- [
pylint] MarkPLE1141fix as unsafe (#13629) - [
flake8-async] Consider async generators to be "checkpoints" forcancel-scope-no-checkpoint(ASYNC100) (#13639) - [
flake8-bugbear] Do not suggest setting parameterstrict=toFalseinB905diagnostic message (#13656) - [
flake8-todos] Only flag the word "TODO", not words starting with "todo" (TD006) (#13640) - [
pycodestyle] Fix whitespace-related false positives and false negatives inside type-parameter lists (E231,E251) (#13704) - [
flake8-simplify] Stabilize preview behavior forSIM115so that the rule can detect files being opened from a wider range of standard-library functions (#12959).
CLI
- Add explanation of fixable in
--statisticscommand (#13774)
Bug fixes
- [
pyflakes] Allowipytestcell magic (F401) (#13745) - [
flake8-use-pathlib] FixPTH123false positive whenopenis passed a file descriptor (#13616) - [
flake8-bandit] Detect patterns from multi line SQL statements (S608) (#13574) - [
flake8-pyi] - Fix dropped expressions inPYI030autofix (#13727)
0.6.9
Preview features
- Fix codeblock dynamic line length calculation for indented docstring examples (#13523)
- [
refurb] MarkFURB118fix as unsafe (#13613)
Rule changes
- [
pydocstyle] Don't raiseD208when last line is non-empty (#13372) - [
pylint] Preserve trivia (i.e. comments) inPLR5501autofix (#13573)
Configuration
- [
pyflakes] Addallow-unused-importssetting forunused-importrule (F401) (#13601)
Bug fixes
- Support ruff discovery in pip build environments (#13591)
- [
flake8-bugbear] Avoid short circuitingB017for multiple context managers (#13609) - [
pylint] Do not offer an invalid fix forPLR1716when the comparisons contain parenthesis (#13527) - [
pyupgrade] FixUP043to apply tocollections.abc.Generatorandcollections.abc.AsyncGenerator(#13611) - [
refurb] Fix handling of slices in tuples forFURB118, e.g.,x[:, 1](#13518)
Documentation
- Update GitHub Action link to
astral-sh/ruff-action(#13551)
0.6.8
Preview features
- Remove unnecessary parentheses around
match caseclauses (#13510) - Parenthesize overlong
ifguards inmatch..caseclauses (#13513) - Detect basic wildcard imports in
ruff analyze graph(#13486) - [
pylint] Implementboolean-chained-comparison(R1716) (#13435)
Rule changes
- [
lake8-simplify] DetectSIM910when using variadic keyword arguments, i.e.,**kwargs(#13503) - [
pyupgrade] Avoid false negatives with non-reference shadowed bindings of loop variables (UP028) (#13504)
Bug fixes
- Detect tuples bound to variadic positional arguments i.e.
*args(#13512) - Exit gracefully on broken pipe errors (#13485)
- Avoid panic when analyze graph hits broken pipe (#13484)
Performance
0.6.7
Preview features
- Add Python version support to ruff analyze CLI (#13426)
- Add
excludesupport toruff analyze(#13425) - Fix parentheses around return type annotations (#13381)
Rule changes
- [
pycodestyle] Fix: Don't autofix if the first line ends in a question mark? (D400) (#13399)
Bug fixes
- Respect
lint.excludein ruff check--add-noqa(#13427)
Performance
- Avoid tracking module resolver files in Salsa (#13437)
- Use
forgetfor module resolver database (#13438)
0.6.6
Preview features
- [
refurb] Skipslice-to-remove-prefix-or-suffix(FURB188) when non-trivial slice steps are present (#13405) - Add a subcommand to generate dependency graphs (#13402)
Formatter
- Fix placement of inline parameter comments (#13379)
Server
- Fix off-by one error in the
LineIndex::offsetcalculation (#13407)
Bug fixes
- [
fastapi] Respect FastAPI aliases in route definitions (#13394) - [
pydocstyle] Respect word boundaries when detecting function signature in docs (#13388)
Documentation
- Add backlinks to rule overview linter (#13368)
- Fix documentation for editor vim plugin ALE (#13348)
- Fix rendering of
FURB188docs (#13406)
0.6.5
Preview features
- [
pydoclint] IgnoreDOC201when function name is "new" (#13300) - [
refurb] Implementslice-to-remove-prefix-or-suffix(FURB188) (#13256)
Rule changes
- [
eradicate] Ignore script-comments with multiple end-tags (ERA001) (#13283) - [
pyflakes] Improve error message forUndefinedNamewhen a builtin was added in a newer version than specified in Ruff config (F821) (#13293)
Server
- Add support for extensionless Python files for server (#13326)
- Fix configuration inheritance for configurations specified in the LSP settings (#13285)
Bug fixes
- [
ruff] Handle unary operators indecimal-from-float-literal(RUF032) (#13275)
CLI
- Only include rules with diagnostics in SARIF metadata (#13268)
Playground
- Add "Copy as pyproject.toml/ruff.toml" and "Paste from TOML" (#13328)
- Fix errors not shown for restored snippet on page load (#13262)
0.6.4
Preview features
- [
flake8-builtins] Use dynamic builtins list based on Python version (#13172) - [
pydoclint] Permit yieldingNoneinDOC402andDOC403(#13148) - [
pylint] Update diagnostic message forPLW3201(#13194) - [
ruff] Implementpost-init-default(RUF033) (#13192) - [
ruff] Implement useless if-else (RUF034) (#13218)
Rule changes
- [
flake8-pyi] Respectpep8_naming.classmethod-decoratorssettings when determining if a method is a classmethod incustom-type-var-return-type(PYI019) (#13162) - [
flake8-pyi] Teach various rules that annotations might be stringized (#12951) - [
pylint] Avoidno-self-useforattrs-style validators (#13166) - [
pylint] Recurse into subscript subexpressions when searching for list/dict lookups (PLR1733,PLR1736) (#13186) - [
pyupgrade] Detectaiofiles.opencalls inUP015(#13173) - [
pyupgrade] Marksys.version_info[0] < 3and similar comparisons as outdated (UP036) (#13175)
CLI
- Enrich messages of SARIF results (#13180)
- Handle singular case for incompatible rules warning in
ruff formatoutput (#13212)
Bug fixes
- [
pydocstyle] Improve heuristics for detecting Google-style docstrings (#13142) - [
refurb] Treatseparguments with effects as unsafe removals (FURB105) (#13165)
0.6.3
Preview features
- [
flake8-simplify] Extendopen-file-with-context-handlerto work withdbm.sqlite3(SIM115) (#13104) - [
pycodestyle] DisableE741in stub files (.pyi) (#13119) - [
pydoclint] AvoidDOC201on explicit returns in functions that only returnNone(#13064)
Rule changes
- [
flake8-async] Disable check forasynciobefore Python 3.11 (ASYNC109) (#13023)
Bug fixes
- [
FastAPI] Avoid introducing invalid syntax in fix forfast-api-non-annotated-dependency(FAST002) (#13133) - [
flake8-implicit-str-concat] Normalize octals before merging concatenated strings insingle-line-implicit-string-concatenation(ISC001) (#13118) - [
flake8-pytest-style] Improve help message forpytest-incorrect-mark-parentheses-style(PT023) (#13092) - [
pylint] Avoid autofix for calls that aren'tminormaxas starred expression (PLW3301) (#13089) - [
ruff] Adddatetime.time,datetime.tzinfo, anddatetime.timezoneas immutable function calls (RUF009) (#13109) - [
ruff] Extend comment deletion forRUF100to include trailing text fromnoqadirectives while preserving any following comments on the same line, if any (#13105) - Fix dark theme on initial page load for the Ruff playground (#13077)
0.6.2
Preview features
- [
flake8-simplify] Extendopen-file-with-context-handlerto work with other standard-library IO modules (SIM115) (#12959) - [
ruff] Avoidunused-asyncfor functions with FastAPI route decorator (RUF029) (#12938) - [
ruff] Ignorefstring-missing-syntax(RUF027) forfastAPIpaths (#12939) - [
ruff] Implement check for Decimal called with a float literal (RUF032) (#12909)
Rule changes
- [
flake8-bugbear] Update diagnostic message when expression is at the end of function (B015) (#12944) - [
flake8-pyi] Skip type annotations instring-or-bytes-too-long(PYI053) (#13002) - [
flake8-type-checking] Always recognise relative imports as first-party (#12994) - [
flake8-unused-arguments] Ignore unused arguments on stub functions (ARG001) (#12966) - [
pylint] Ignore augmented assignment forself-cls-assignment(PLW0642) (#12957)
Server
- Show full context in error log messages (#13029)
Bug fixes
- [
pep8-naming] Don't flagfromimports following conventional import names (N817) (#12946) - [
pylint] - Allow__new__methods to haveclsas their first argument even if decorated with@staticmethodforbad-staticmethod-argument(PLW0211) (#12958)
Documentation
- Add
hyperfineinstallation instructions; updatehyperfinecode samples (#13034) - Expand note to use Ruff with other language server in Kate (#12806)
- Update example for
PT001as per the new default behavior (#13019) - [
perflint] Improve docs fortry-except-in-loop(PERF203) (#12947) - [
pydocstyle] Add reference tolint.pydocstyle.ignore-decoratorssetting to rule docs (#12996)
0.6.1
This is a hotfix release to address an issue with ruff-pre-commit. In v0.6,
Ruff changed its behavior to lint and format Jupyter notebooks by default;
however, due to an oversight, these files were still excluded by default if
Ruff was run via pre-commit, leading to inconsistent behavior.
This has now been fixed.
Preview features
- [
fastapi] Implementfast-api-unused-path-parameter(FAST003) (#12638)
Rule changes
- [
pylint] Renametoo-many-positionaltotoo-many-positional-arguments(R0917) (#12905)
Server
- Fix crash when applying "fix-all" code-action to notebook cells (#12929)
Other changes
- [
flake8-naming]: Respect import conventions (N817) (#12922)
0.6.0
Check out the blog post for a migration guide and overview of the changes!
Breaking changes
See also, the "Remapped rules" section which may result in disabled rules.
- Lint and format Jupyter Notebook by default (#12878).
- Detect imports in
srclayouts by default forisortrules (#12848) - The pytest rules
PT001andPT023now default to omitting the decorator parentheses when there are no arguments (#12838).
Deprecations
The following rules are now deprecated:
pytest-missing-fixture-name-underscore(PT004)pytest-incorrect-fixture-name-underscore(PT005)unpacked-list-comprehension(UP027)
Remapped rules
The following rules have been remapped to new rule codes:
unnecessary-dict-comprehension-for-iterable:RUF025toC420
Stabilization
The following rules have been stabilized and are no longer in preview:
singledispatch-method(PLE1519)singledispatchmethod-function(PLE1520)bad-staticmethod-argument(PLW0211)if-stmt-min-max(PLR1730)invalid-bytes-return-type(PLE0308)invalid-hash-return-type(PLE0309)invalid-index-return-type(PLE0305)invalid-length-return-type(PLEE303)self-or-cls-assignment(PLW0642)byte-string-usage(PYI057)duplicate-literal-member(PYI062)redirected-noqa(RUF101)
The following behaviors have been stabilized:
cancel-scope-no-checkpoint(ASYNC100): Supportasyncioandanyiocontext managers.async-function-with-timeout(ASYNC109): Supportasyncioandanyiocontext managers.async-busy-wait(ASYNC110): Supportasyncioandanyiocontext managers.async-zero-sleep(ASYNC115): Supportanyiocontext managers.long-sleep-not-forever(ASYNC116): Supportanyiocontext managers.
The following fixes have been stabilized:
superfluous-else-return(RET505)superfluous-else-raise(RET506)superfluous-else-continue(RET507)superfluous-else-break(RET508)
Preview features
- [
flake8-simplify] Further simplify to binary in preview for (SIM108) (#12796) - [
pyupgrade] Show violations without auto-fix (UP031) (#11229)
Rule changes
- [
flake8-import-conventions] Addxml.etree.ElementTreeto default conventions (#12455) - [
flake8-pytest-style] Add a space after comma in CSV output (PT006) (#12853)
Server
- Show a message for incorrect settings (#12781)
Bug fixes
- [
flake8-async] Do not lint yield in context manager (ASYNC100) (#12896) - [
flake8-comprehensions] Do not lintasync forcomprehensions (C419) (#12895) - [
flake8-return] Only add returnNoneat end of a function (RET503) (#11074) - [
flake8-type-checking] Avoid treatingdataclasses.KW_ONLYas typing-only (TCH003) (#12863) - [
pep8-naming] Treattype(Protocol)et al as metaclass base (N805) (#12770) - [
pydoclint] Don't enforce returns and yields in abstract methods (DOC201,DOC202) (#12771) - [
ruff] Skip tuples with slice expressions in (RUF031) (#12768) - [
ruff] Ignore unparenthesized tuples in subscripts when the subscript is a type annotation or type alias (RUF031) (#12762) - [
ruff] Ignore template strings passed to logging andbuiltins._()calls (RUF027) (#12889) - [
ruff] Do not remove parens for tuples with starred expressions in Python <=3.10 (RUF031) (#12784) - Evaluate default parameter values for a function in that function's enclosing scope (#12852)
Other changes
- Respect VS Code cell metadata when detecting the language of Jupyter Notebook cells (#12864)
- Respect
kernelspecnotebook metadata when detecting the preferred language for a Jupyter Notebook (#12875)
0.5.7
Preview features
- [
flake8-comprehensions] Account for list and set comprehensions inunnecessary-literal-within-tuple-call(C409) (#12657) - [
flake8-pyi] Add autofix forfuture-annotations-in-stub(PYI044) (#12676) - [
flake8-return] Avoid syntax error when auto-fixingRET505with mixed indentation (space and tabs) (#12740) - [
pydoclint] Adddocstring-missing-yields(DOC402) anddocstring-extraneous-yields(DOC403) (#12538) - [
pydoclint] AvoidDOC201if docstring begins with "Return", "Returns", "Yield", or "Yields" (#12675) - [
pydoclint] Deduplicate collected exceptions after traversing function bodies (DOC501) (#12642) - [
pydoclint] IgnoreDOCerrors for stub functions (#12651) - [
pydoclint] Teach rules to understand reraised exceptions as being explicitly raised (DOC501,DOC502) (#12639) - [
ruff] Implementincorrectly-parenthesized-tuple-in-subscript(RUF031) (#12480) - [
ruff] MarkRUF023fix as unsafe if__slots__is not a set and the binding is used elsewhere (#12692)
Rule changes
- [
refurb] Add autofix forimplicit-cwd(FURB177) (#12708) - [
ruff] Add autofix forzip-instead-of-pairwise(RUF007) (#12663) - [
tryceratops] AddBaseExceptiontoraise-vanilla-classrule (TRY002) (#12620)
Server
- Ignore non-file workspace URL; Ruff will display a warning notification in this case (#12725)
CLI
- Fix cache invalidation for nested
pyproject.tomlfiles (#12727)
Bug fixes
- [
flake8-async] Fix false positives with multipleasync withitems (ASYNC100) (#12643) - [
flake8-bandit] Avoid false-positives for list concatenations in SQL construction (S608) (#12720) - [
flake8-bugbear] Treatreturnas equivalent tobreak(B909) (#12646) - [
flake8-comprehensions] Set comprehensions not a violation forsuminunnecessary-comprehension-in-call(C419) (#12691) - [
flake8-simplify] Parenthesize conditions based on precedence when merging if arms (SIM114) (#12737) - [
pydoclint] Try both 'Raises' section styles when convention is unspecified (DOC501) (#12649)
0.5.6
Ruff 0.5.6 automatically enables linting and formatting of notebooks in preview mode.
You can opt-out of this behavior by adding *.ipynb to the extend-exclude setting.
[tool.ruff]
extend-exclude = ["*.ipynb"]
Preview features
- Enable notebooks by default in preview mode (#12621)
- [
flake8-builtins] Implement import, lambda, and module shadowing (#12546) - [
pydoclint] Adddocstring-missing-returns(DOC201) anddocstring-extraneous-returns(DOC202) (#12485)
Rule changes
- [
flake8-return] Exempt cached properties and other property-like decorators from explicit return rule (RET501) (#12563)
Server
- Make server panic hook more error resilient (#12610)
- Use
$/logTracefor server trace logs in Zed and VS Code (#12564) - Keep track of deleted cells for reorder change request (#12575)
Configuration
- [
flake8-implicit-str-concat] Always allow explicit multi-line concatenations when implicit concatenations are banned (#12532)
Bug fixes
- [
flake8-async] Avoid flaggingasyncio.timeouts as unused when the context manager includesasyncio.TaskGroup(#12605) - [
flake8-slots] Avoid recommending__slots__for classes that inherit from more thannamedtuple(#12531) - [
isort] Avoid marking required imports as unused (#12537) - [
isort] Preserve trailing inline comments on import-from statements (#12498) - [
pycodestyle] Add newlines before comments (E305) (#12606) - [
pycodestyle] Don't attach comments with mismatched indents (#12604) - [
pyflakes] Fix preview-mode bugs inF401when attempting to autofix unused first-party submodule imports in an__init__.pyfile (#12569) - [
pylint] Respect start index inunnecessary-list-index-lookup(#12603) - [
pyupgrade] Avoid recommending no-argument super inslots=Truedataclasses (#12530) - [
pyupgrade] Use colon rather than dot formatting for integer-only types (#12534) - Fix NFKC normalization bug when removing unused imports (#12571)
Other changes
- Consider more stdlib decorators to be property-like (#12583)
- Improve handling of metaclasses in various linter rules (#12579)
- Improve consistency between linter rules in determining whether a function is property (#12581)
0.5.5
Preview features
- [
fastapi] Implementfastapi-redundant-response-model(FAST001) andfastapi-non-annotated-dependency(FAST002) (#11579) - [
pydoclint] Implementdocstring-missing-exception(DOC501) anddocstring-extraneous-exception(DOC502) (#11471)
Rule changes
- [
numpy] Fix NumPy 2.0 rule fornp.alltrueandnp.sometrue(#12473) - [
numpy] IgnoreNPY201insideexceptblocks for compatibility with older numpy versions (#12490) - [
pep8-naming] Avoid applyingignore-namestoselfandclsfunction names (N804,N805) (#12497)
Formatter
- Fix incorrect placement of leading function comment with type params (#12447)
Server
- Do not bail code action resolution when a quick fix is requested (#12462)
Bug fixes
- Fix
Ordimplementation ofcmp_fix(#12471) - Raise syntax error for unparenthesized generator expression in multi-argument call (#12445)
- [
pydoclint] Fix panic inDOC501reported in #12428 (#12435) - [
flake8-bugbear] Allow singleton tuples with starred expressions inB013(#12484)
Documentation
- Add Eglot setup guide for Emacs editor (#12426)
- Add note about the breaking change in
nvim-lspconfig(#12507) - Add note to include notebook files for native server (#12449)
- Add setup docs for Zed editor (#12501)
0.5.4
Rule changes
- [
ruff] RenameRUF007tozip-instead-of-pairwise(#12399)
Bug fixes
- [
flake8-builtins] Avoid shadowing diagnostics for@overridemethods (#12415) - [
flake8-comprehensions] Insert parentheses for multi-argument generators (#12422) - [
pydocstyle] Handle escaped docstrings within docstring (D301) (#12192)
Documentation
0.5.3
Ruff 0.5.3 marks the stable release of the Ruff language server and introduces revamped documentation, including setup guides for your editor of choice and the language server itself.
Preview features
- Formatter: Insert empty line between suite and alternative branch after function/class definition (#12294)
- [
pyupgrade] Implementunnecessary-default-type-args(UP043) (#12371)
Rule changes
- [
flake8-bugbear] Detect enumerate iterations inloop-iterator-mutation(B909) (#12366) - [
flake8-bugbear] Removediscard,remove, andpopallowance forloop-iterator-mutation(B909) (#12365) - [
pylint] Allowrepeated-equality-comparisonfor mixed operations (PLR1714) (#12369) - [
pylint] Ignoreselfandclswhen counting arguments (PLR0913) (#12367) - [
pylint] Use UTF-8 as default encoding inunspecified-encodingfix (PLW1514) (#12370)
Server
- Build settings index in parallel for the native server (#12299)
- Use fallback settings when indexing the project (#12362)
- Consider
--previewflag forserversubcommand for the linter and formatter (#12208)
Bug fixes
- [
flake8-comprehensions] Allow additional arguments forsumandmaxcomprehensions (C419) (#12364) - [
pylint] Avoid dropping extra boolean operations inrepeated-equality-comparison(PLR1714) (#12368) - [
pylint] Consider expression before statement when determining binding kind (PLR1704) (#12346)
Documentation
- Add docs for Ruff language server (#12344)
- Migrate to standalone docs repo (#12341)
- Update versioning policy for editor integration (#12375)
Other changes
- Publish Wasm API to npm (#12317)
0.5.2
Preview features
- Use
spaceseparator before parenthesized expressions in comprehensions with leading comments (#12282) - [
flake8-async] UpdateASYNC100to includeanyioandasyncio(#12221) - [
flake8-async] UpdateASYNC109to includeanyioandasyncio(#12236) - [
flake8-async] UpdateASYNC110to includeanyioandasyncio(#12261) - [
flake8-async] UpdateASYNC115to includeanyioandasyncio(#12262) - [
flake8-async] UpdateASYNC116to includeanyioandasyncio(#12266)
Rule changes
- [
flake8-return] Exempt properties from explicit return rule (RET501) (#12243) - [
numpy] Addnp.NAN-to-np.nandiagnostic (#12292) - [
refurb] Makelist-reverse-copyan unsafe fix (#12303)
Server
- Consider
includeandextend-includesettings in native server (#12252) - Include nested configurations in settings reloading (#12253)
CLI
- Omit code frames for fixes with empty ranges (#12304)
- Warn about formatter incompatibility for
D203(#12238)
Bug fixes
- Make cache-write failures non-fatal on Windows (#12302)
- Treat
notoperations as boolean tests (#12301) - [
flake8-bandit] AvoidS310violations for HTTP-safe f-strings (#12305) - [
flake8-bandit] Support explicit string concatenations in S310 HTTP detection (#12315) - [
flake8-bandit] fix S113 false positive for httpx withouttimeoutargument (#12213) - [
pycodestyle] Remove "non-obvious" allowance for E721 (#12300) - [
pyflakes] Considerwithblocks as single-item branches for redefinition analysis (#12311) - [
refurb] Restrict forwarding fornewlineargument inopen()calls to Python versions >= 3.10 (#12244)
Documentation
- Update help and documentation to reflect
--output-format fulldefault (#12248)
Performance
- Use more threads when discovering Python files (#12258)
0.5.1
Preview features
- [
flake8-bugbear] Implement mutable-contextvar-default (B039) (#12113) - [
pycodestyle] Whitespace after decorator (E204) (#12140) - [
pytest] ReversePT001andPT0023defaults (#12106)
Rule changes
- Enable token-based rules on source with syntax errors (#11950)
- [
flake8-bandit] DetecthttpxforS113(#12174) - [
numpy] UpdateNPY201to include exception deprecations (#12065) - [
pylint] Generate autofix forduplicate-bases(PLE0241) (#12105)
Server
- Avoid syntax error notification for source code actions (#12148)
- Consider the content of the new cells during notebook sync (#12203)
- Fix replacement edit range computation (#12171)
Bug fixes
- Disable auto-fix when source has syntax errors (#12134)
- Fix cache key collisions for paths with separators (#12159)
- Make
requires-pythoninference robust to==(#12091) - Use char-wise width instead of
str-width (#12135) - [
pycodestyle] AvoidE275if keyword followed by comma (#12136) - [
pycodestyle] AvoidE275if keyword is followed by a semicolon (#12095) - [
pylint] Skip dummy variables forPLR1704(#12190)
Performance
0.5.0
Check out the blog post for a migration guide and overview of the changes!
Breaking changes
See also, the "Remapped rules" section which may result in disabled rules.
- Follow the XDG specification to discover user-level configurations on macOS (same as on other Unix platforms)
- Selecting
ALLnow excludes deprecated rules - The released archives now include an extra level of nesting, which can be removed with
--strip-components=1when untarring. - The release artifact's file name no longer includes the version tag. This enables users to install via
/latestURLs on GitHub. - The diagnostic ranges for some
flake8-banditrules were modified (#10667).
Deprecations
The following rules are now deprecated:
syntax-error(E999): Syntax errors are now always shown
Remapped rules
The following rules have been remapped to new rule codes:
blocking-http-call-in-async-function:ASYNC100toASYNC210open-sleep-or-subprocess-in-async-function:ASYNC101split intoASYNC220,ASYNC221,ASYNC230, andASYNC251blocking-os-call-in-async-function:ASYNC102has been merged intoASYNC220andASYNC221trio-timeout-without-await:TRIO100toASYNC100trio-sync-call:TRIO105toASYNC105trio-async-function-with-timeout:TRIO109toASYNC109trio-unneeded-sleep:TRIO110toASYNC110trio-zero-sleep-call:TRIO115toASYNC115repeated-isinstance-calls:PLR1701toSIM101
Stabilization
The following rules have been stabilized and are no longer in preview:
mutable-fromkeys-value(RUF024)default-factory-kwarg(RUF026)django-extra(S610)manual-dict-comprehension(PERF403)print-empty-string(FURB105)readlines-in-for(FURB129)if-expr-min-max(FURB136)bit-count(FURB161)redundant-log-base(FURB163)regex-flag-alias(FURB167)isinstance-type-none(FURB168)type-none-comparison(FURB169)implicit-cwd(FURB177)hashlib-digest-hex(FURB181)list-reverse-copy(FURB187)bad-open-mode(PLW1501)empty-comment(PLR2044)global-at-module-level(PLW0604)misplaced-bare-raise(PLE0744)non-ascii-import-name(PLC2403)non-ascii-name(PLC2401)nonlocal-and-global(PLE0115)potential-index-error(PLE0643)redeclared-assigned-name(PLW0128)redefined-argument-from-local(PLR1704)repeated-keyword-argument(PLE1132)super-without-brackets(PLW0245)unnecessary-list-index-lookup(PLR1736)useless-exception-statement(PLW0133)useless-with-lock(PLW2101)
The following behaviors have been stabilized:
is-literal(F632) now warns for identity checks against list, set or dictionary literalsneedless-bool(SIM103) now detectsifexpressions with implicitelsebranchesmodule-import-not-at-top-of-file(E402) now allowsos.environmodifications between import statementstype-comparison(E721) now allows idioms such astype(x) is intyoda-condition(SIM300) now flags a wider range of expressions
Removals
The following deprecated settings have been removed:
output-format=text; useoutput-format=conciseoroutput-format=fulltab-size; useindent-width
The following deprecated CLI options have been removed:
--show-source; use--output-format=full--no-show-source; use--output-format=concise
The following deprecated CLI commands have been removed:
ruff <path>; useruff check <path>ruff --clean; useruff cleanruff --generate-shell-completion; useruff generate-shell-completion
Preview features
- [
ruff] Addassert-with-print-messagerule (#11981)
CLI
- Use rule name rather than message in
--statistics(#11697) - Use the output format
fullby default (#12010) - Don't log syntax errors to the console (#11902)
Rule changes
- [
ruff] Fix false positives ifgettextis imported using an alias (RUF027) (#12025) - [
numpy] Updatetrapzandin1ddeprecation (NPY201) (#11948) - [
flake8-bandit] Modify diagnostic ranges for shell-related rules (#10667)
Server
- Closing an untitled, unsaved notebook document no longer throws an error (#11942)
- Support the usage of tildes and environment variables in
logFile(#11945) - Add option to configure whether to show syntax errors (#12059)
Bug fixes
- [
pycodestyle] AvoidE203for f-string debug expression (#12024) - [
pep8-naming] Match import-name ignores against both name and alias (N812,N817) (#12033) - [
pyflakes] Detect assignments that shadow definitions (F811) (#11961)
Parser
- Emit a syntax error for an empty type parameter list (#12030)
- Avoid consuming the newline for unterminated strings (#12067)
- Do not include the newline in the unterminated string range (#12017)
- Use the correct range to highlight line continuation errors (#12016)
- Consider 2-character EOL before line continuations (#12035)
- Consider line continuation character for re-lexing (#12008)
Other changes
- Upgrade the Unicode table used for measuring the line-length (#11194)
- Remove the deprecation error message for the nursery selector (#10172)
0.4.10
Parser
- Implement re-lexing logic for better error recovery (#11845)
Rule changes
- [
flake8-copyright] UpdateCPY001to check the first 4096 bytes instead of 1024 (#11927) - [
pycodestyle] UpdateE999to show all syntax errors instead of just the first one (#11900)
Server
- Add tracing setup guide to Helix documentation (#11883)
- Add tracing setup guide to Neovim documentation (#11884)
- Defer notebook cell deletion to avoid an error message (#11864)
Security
- Guard against malicious ecosystem comment artifacts (#11879)
0.4.9
Preview features
- [
pylint] Implementconsider-dict-items(C0206) (#11688) - [
refurb] Implementrepeated-global(FURB154) (#11187)
Rule changes
- [
pycodestyle] Adapt fix forE203to work identical toruff format(#10999)
Formatter
- Fix formatter instability for lines only consisting of zero-width characters (#11748)
Server
- Add supported commands in server capabilities (#11850)
- Use real file path when available in
ruff server(#11800) - Improve error message when a command is run on an unavailable document (#11823)
- Introduce the
ruff.printDebugInformationcommand (#11831) - Tracing system now respects log level and trace level, with options to log to a file (#11747)
CLI
- Handle non-printable characters in diff view (#11687)
Bug fixes
- [
refurb] Avoid suggesting starmap when arguments are used outside call (FURB140) (#11830) - [
flake8-bugbear] Avoid panic inB909when checking large loop blocks (#11772) - [
refurb] Fix misbehavior ofoperator.itemgetterwhen getter param is a tuple (FURB118) (#11774)
0.4.8
Performance
- Linter performance has been improved by around 10% on some microbenchmarks by refactoring the lexer and parser to maintain synchronicity between them (#11457)
Preview features
- [
flake8-bugbear] Implementreturn-in-generator(B901) (#11644) - [
flake8-pyi] Implementpep484-style-positional-only-parameter(PYI063) (#11699) - [
pygrep_hooks] Check blanket ignores via file-level pragmas (PGH004) (#11540)
Rule changes
- [
pyupgrade] UpdateUP035for Python 3.13 and the latest version oftyping_extensions(#11693) - [
numpy] UpdateNPY001rule for NumPy 2.0 (#11735)
Server
- Formatting a document with syntax problems no longer spams a visible error popup (#11745)
CLI
- Add RDJson support for
--output-formatflag (#11682)
Bug fixes
- [
pyupgrade] Write empty string in lieu of panic when fixingUP032(#11696) - [
flake8-simplify] Simplify double negatives inSIM103(#11684) - Ensure the expression generator adds a newline before
typestatements (#11720) - Respect per-file ignores for blanket and redirected noqa rules (#11728)
0.4.7
Preview features
- [
flake8-pyi] ImplementPYI064(#11325) - [
flake8-pyi] ImplementPYI066(#11541) - [
flake8-pyi] ImplementPYI057(#11486) - [
pyflakes] EnableF822in__init__.pyfiles by default (#11370)
Formatter
- Fix incorrect placement of trailing stub function comments (#11632)
Server
- Respect file exclusions in
ruff server(#11590) - Add support for documents not exist on disk (#11588)
- Add Vim and Kate setup guide for
ruff server(#11615)
Bug fixes
- Avoid removing newlines between docstring headers and rST blocks (#11609)
- Infer indentation with imports when logical indent is absent (#11608)
- Use char index rather than position for indent slice (#11645)
- [
flake8-comprehension] Strip parentheses around generators inC400(#11607) - Mark
repeated-isinstance-callsas unsafe on Python 3.10 and later (#11622)
0.4.6
Breaking changes
- Use project-relative paths when calculating GitLab fingerprints (#11532)
- Bump minimum supported Windows version to Windows 10 (#11613)
Preview features
- [
flake8-async] Sleep with >24 hour interval should usually sleep forever (ASYNC116) (#11498)
Rule changes
- [
numpy] Add missing functions to NumPy 2.0 migration rule (#11528) - [
mccabe] Consider irrefutable pattern similar toif .. elseforC901(#11565) - Consider
match-casestatements forC901,PLR0912, andPLR0915(#11521) - Remove empty strings when converting to f-string (
UP032) (#11524) - [
flake8-bandit]request-without-timeoutshould warn forrequests.request(#11548) - [
flake8-self] Ignore sunder accesses inflake8-selfrules (#11546) - [
pyupgrade] Lint forTypeAliasTypeusages (UP040) (#11530)
Server
- Respect excludes in
ruff serverconfiguration discovery (#11551) - Use default settings if initialization options is empty or not provided (#11566)
ruff servercorrectly treats.pyifiles as stub files (#11535)ruff serversearches for configuration in parent directories (#11537)ruff server: An empty code action filter no longer returns notebook source actions (#11526)
Bug fixes
- [
flake8-logging-format] Fix autofix title inlogging-warn(G010) (#11514) - [
refurb] Avoid recommendingoperator.itemgetterwith dependence on lambda arguments (#11574) - [
flake8-simplify] Avoid recommending context manager in__enter__implementations (#11575) - Create intermediary directories for
--output-file(#11550) - Propagate reads on global variables (#11584)
- Treat all
singledispatcharguments as runtime-required (#11523)
0.4.5
Ruff's language server is now in Beta
v0.4.5 marks the official Beta release of ruff server, an integrated language server built into Ruff.
ruff server supports the same feature set as ruff-lsp, powering linting, formatting, and
code fixes in Ruff's editor integrations -- but with superior performance and
no installation required. We'd love your feedback!
You can enable ruff server in the VS Code extension today.
To read more about this exciting milestone, check out our blog post!
Rule changes
- [
flake8-future-annotations] Rewordfuture-rewritable-type-annotation(FA100) message (#11381) - [
isort] Expanded the set of standard-library modules to include_string, etc. (#11374) - [
pycodestyle] Consider soft keywords forE27rules (#11446) - [
pyflakes] Recommend adding unused import bindings to__all__(#11314) - [
pyflakes] Update documentation and deprecateignore_init_module_imports(#11436) - [
pyupgrade] Mark quotes as unnecessary for non-evaluated annotations (#11485)
Formatter
- Avoid multiline quotes warning with
quote-style = preserve(#11490)
Server
- Support Jupyter Notebook files (#11206)
- Support
noqacomment code actions (#11276) - Fix automatic configuration reloading (#11492)
- Fix several issues with configuration in Neovim and Helix (#11497)
CLI
- Add
--output-formatas a CLI option forruff config(#11438)
Bug fixes
- Avoid
PLE0237for property with setter (#11377) - Avoid
TCH005forifstmt withelif/elseblock (#11376) - Avoid flagging
__future__annotations as required for non-evaluated type annotations (#11414) - Check for ruff executable in 'bin' directory as installed by 'pip install --target'. (#11450)
- Sort edits prior to deduplicating in quotation fix (#11452)
- Treat escaped newline as valid sequence (#11465)
- [
flake8-pie] Preserve parentheses inunnecessary-dict-kwargs(#11372) - [
pylint] Ignore__slots__with dynamic values (#11488) - [
pylint] Removetrybody from branch counting (#11487) - [
refurb] Respect operator precedence inFURB110(#11464)
Documentation
- Add
--previewto the README (#11395) - Add Python 3.13 to list of allowed Python versions (#11411)
- Simplify Neovim setup documentation (#11489)
- Update CONTRIBUTING.md to reflect the new parser (#11434)
- Update server documentation with new migration guide (#11499)
- [
pycodestyle] Clarify motivation forE713andE714(#11483) - [
pyflakes] Update docs to describe WAI behavior (F541) (#11362) - [
pylint] Clearly indicate what is counted as a branch (#11423)
0.4.4
Preview features
- [
pycodestyle] Ignore end-of-line comments when determining blank line rules (#11342) - [
pylint] Detectpathlib.Path.opencalls inunspecified-encoding(PLW1514) (#11288) - [
flake8-pyi] ImplementPYI059(generic-not-last-base-class) (#11233) - [
flake8-pyi] ImplementPYI062(duplicate-literal-member) (#11269)
Rule changes
- [
flake8-boolean-trap] Allow passing booleans as positional-only arguments in code such asset(True)(#11287) - [
flake8-bugbear] Ignore enum classes incached-instance-method(B019) (#11312)
Server
- Expand tildes when resolving Ruff server configuration file (#11283)
- Fix
ruff serverhanging after Neovim closes (#11291) - Editor settings are used by default if no file-based configuration exists (#11266)
Bug fixes
- [
pylint] Considerwithstatements fortoo-many-branches(PLR0912) (#11321) - [
flake8-blind-except,tryceratops] Respect logged and re-raised expressions in nested statements (BLE001,TRY201) (#11301) - Recognise assignments such as
__all__ = builtins.list(["foo", "bar"])as valid__all__definitions (#11335)
0.4.3
Enhancements
- Add support for PEP 696 syntax (#11120)
Preview features
- [
refurb] Use function range forreimplemented-operatordiagnostics (#11271) - [
refurb] Ignore methods inreimplemented-operator(FURB118) (#11270) - [
refurb] Implementfstring-number-format(FURB116) (#10921) - [
ruff] Implementredirected-noqa(RUF101) (#11052) - [
pyflakes] Distinguish between first-party and third-party imports for fix suggestions (#11168)
Rule changes
- [
flake8-bugbear] Ignore non-abstract class attributes when enforcingB024(#11210) - [
flake8-logging] Include inline instantiations when detecting loggers (#11154) - [
pylint] Also emitPLR0206for properties with variadic parameters (#11200) - [
ruff] Detect duplicate codes as part ofunused-noqa(RUF100) (#10850)
Formatter
- Avoid multiline expression if format specifier is present (#11123)
LSP
- Write
ruff serversetup guide for Helix (#11183) ruff serverno longer hangs after shutdown (#11222)ruff serverreads from a configuration TOML file in the user configuration directory if no local configuration exists (#11225)ruff serverrespectsper-file-ignoresconfiguration (#11224)ruff server: Support a custom TOML configuration file (#11140)ruff server: Support setting to prioritize project configuration over editor configuration (#11086)
Bug fixes
- Avoid debug assertion around NFKC renames (#11249)
- [
pyflakes] Prioritizeredefined-while-unusedoverunused-import(#11173) - [
ruff] Respectasyncexpressions in comprehension bodies (#11219) - [
pygrep_hooks] Fixblanket-noqapanic when last line has noqa with no newline (PGH004) (#11108) - [
perflint] Ignore list-copy recommendations for asyncforloops (#11250) - [
pyflakes] Improveinvalid-print-syntaxdocumentation (#11171)
Performance
Windows
- Increase the minimum requirement to Windows 10.
0.4.2
Rule changes
- [
flake8-pyi] Allow for overloaded__exit__and__aexit__definitions (PYI036) (#11057) - [
pyupgrade] Catch usages of"%s" % varand provide an unsafe fix (UP031) (#11019) - [
refurb] Implement new rule that suggests min/max oversorted()(FURB192) (#10868)
Server
- Fix an issue with missing diagnostics for Neovim and Helix (#11092)
- Implement hover documentation for
noqacodes (#11096) - Introduce common Ruff configuration options with new server settings (#11062)
Bug fixes
- Use
macos-12for building release wheels to enable macOS 11 compatibility (#11146) - [
flake8-blind-expect] Allow raise from inBLE001(#11131) - [
flake8-pyi] Allow simple assignments toNonein enum class scopes (PYI026) (#11128) - [
flake8-simplify] Avoid raisingSIM911for non-zipattribute calls (#11126) - [
refurb] Avoidoperator.itemgettersuggestion for single-item tuple (#11095) - [
ruff] Respect per-file-ignores forRUF100with no other diagnostics (#11058) - [
ruff] Fix async comprehension false positive (RUF029) (#11070)
Documentation
- [
flake8-bugbear] Document explicitly disabling strict zip (B905) (#11040) - [
flake8-type-checking] Mentionlint.typing-modulesinTCH001,TCH002, andTCH003(#11144) - [
isort] Improve documentation around customisortsections (#11050) - [
pylint] Fix documentation oversight forinvalid-X-returns(#11094)
Performance
- Use
matchitto resolve per-file settings (#11111)
0.4.1
Preview features
- [
pylint] Implementinvalid-hash-returned(PLE0309) (#10961) - [
pylint] Implementinvalid-index-returned(PLE0305) (#10962)
Bug fixes
- [
pylint] AllowNoReturn-like functions for__str__,__len__, etc. (PLE0307) (#11017) - Parser: Use empty range when there's "gap" in token source (#11032)
- [
ruff] Ignore stub functions inunused-async(RUF029) (#11026) - Parser: Expect indented case block instead of match stmt (#11033)
0.4.0
A new, hand-written parser
Ruff's new parser is >2x faster, which translates to a 20-40% speedup for all linting and formatting invocations. There's a lot to say about this exciting change, so check out the blog post for more details!
See #10036 for implementation details.
A new language server in Rust
With this release, we also want to highlight our new language server. ruff server is a Rust-powered language
server that comes built-in with Ruff. It can be used with any editor that supports the Language Server Protocol (LSP).
It uses a multi-threaded, lock-free architecture inspired by rust-analyzer and it will open the door for a lot
of exciting features. It’s also faster than our previous Python-based language server
-- but you probably guessed that already.
ruff server is only in alpha, but it has a lot of features that you can try out today:
- Lints Python files automatically and shows quick-fixes when available
- Formats Python files, with support for range formatting
- Comes with commands for quickly performing actions:
ruff.applyAutofix,ruff.applyFormat, andruff.applyOrganizeImports - Supports
source.fixAllandsource.organizeImportssource actions - Automatically reloads your project configuration when you change it
To setup ruff server with your editor, refer to the README.md.
Preview features
- [
pycodestyle] Do not triggerE3rules ondefs following a function/method with a dummy body (#10704) - [
pylint] Implementinvalid-bytes-returned(E0308) (#10959) - [
pylint] Implementinvalid-length-returned(E0303) (#10963) - [
pylint] Implementself-cls-assignment(W0642) (#9267) - [
pylint] Omit stubs frominvalid-boolandinvalid-str-return-type(#11008) - [
ruff] New ruleunused-async(RUF029) to detect unneededasynckeywords on functions (#9966)
Rule changes
- [
flake8-bandit] Allowurllib.request.urlopencalls with staticRequestargument (S310) (#10964) - [
flake8-bugbear] Treatraise NotImplemented-only bodies as stub functions (B006) (#10990) - [
flake8-slots] Respect same-fileEnumsubclasses (SLOT000) (#11006) - [
pylint] Support inverted comparisons (PLR1730) (#10920)
Linter
- Improve handling of builtin symbols in linter rules (#10919)
- Improve display of rules in
--show-settings(#11003) - Improve inference capabilities of the
BuiltinTypeChecker(#10976) - Resolve classes and functions relative to script name (#10965)
- Improve performance of
RuleTable::any_enabled(#10971)
Server
This section is devoted to updates for our new language server, written in Rust.
- Enable ruff-specific source actions (#10916)
- Refreshes diagnostics for open files when file configuration is changed (#10988)
- Important errors are now shown as popups (#10951)
- Introduce settings for directly configuring the linter and formatter (#10984)
- Resolve configuration for each document individually (#10950)
- Write a setup guide for Neovim (#10987)
Configuration
- Add
RUFF_OUTPUT_FILEenvironment variable support (#10992)
Bug fixes
- Avoid
non-augmented-assignmentfor reversed, non-commutative operators (PLR6104) (#10909) - Limit commutative non-augmented-assignments to primitive data types (
PLR6104) (#10912) - Respect
per-file-ignoresforRUF100on blanket# noqa(#10908) - Consider
ifexpression for parenthesized with items parsing (#11010) - Consider binary expr for parenthesized with items parsing (#11012)
- Reset
FOR_TARGETcontext for all kinds of parentheses (#11009)
0.3.7
Preview features
- [
flake8-bugbear] Implementloop-iterator-mutation(B909) (#9578) - [
pylint] Implement rule to prefer augmented assignment (PLR6104) (#9932)
Bug fixes
- Avoid TOCTOU errors in cache initialization (#10884)
- [
pylint] Recodenan-comparisonrule toW0177(#10894) - [
pylint] Reverse min-max logic inif-stmt-min-max(#10890)
0.3.6
Preview features
- [
pylint] Implementbad-staticmethod-argument(PLW0211) (#10781) - [
pylint] Implementif-stmt-min-max(PLR1730,PLR1731) (#10002) - [
pyupgrade] Replacestr,Enummultiple inheritance withStrEnumUP042(#10713) - [
refurb] Implementif-expr-instead-of-or-operator(FURB110) (#10687) - [
refurb] Implementint-on-sliced-str(FURB166) (#10650) - [
refurb] Implementwrite-whole-file(FURB103) (#10802) - [
refurb] Supportitemgetterinreimplemented-operator(FURB118) (#10526) - [
flake8_comprehensions] Addsum/min/maxto unnecessary comprehension check (C419) (#10759)
Rule changes
- [
pydocstyle] Require capitalizing docstrings where the first sentence is a single word (D403) (#10776) - [
pycodestyle] Ignore annotated lambdas in class scopes (E731) (#10720) - [
flake8-pyi] Various improvements to PYI034 (#10807) - [
flake8-slots] Flag subclasses of call-basedtyping.NamedTuples as well as subclasses ofcollections.namedtuple()(SLOT002) (#10808) - [
pyflakes] Allow forward references in class bases in stub files (F821) (#10779) - [
pygrep-hooks] Improveblanket-noqaerror message (PGH004) (#10851)
CLI
- Support
FORCE_COLORenv var (#10839)
Configuration
- Support negated patterns in
[extend-]per-file-ignores(#10852)
Bug fixes
- [
flake8-import-conventions] Accept non-aliased (but correct) import inunconventional-import-alias(ICN001) (#10729) - [
flake8-quotes] Add semantic model flag when inside f-string replacement field (#10766) - [
pep8-naming] Recursively resolveTypeDictsfor N815 violations (#10719) - [
flake8-quotes] RespectQ00*ignores inflake8-quotesrules (#10728) - [
flake8-simplify] Show negated condition inneedless-booldiagnostics (SIM103) (#10854) - [
ruff] Use within-scope shadowed bindings inasyncio-dangling-task(RUF006) (#10793) - [
flake8-pytest-style] Fix single-tuple conversion inpytest-parametrize-values-wrong-type(PT007) (#10862) - [
flake8-return] Ignore assignments to annotated variables inunnecessary-assign(RET504) (#10741) - [
refurb] Do not allow any keyword arguments forread-whole-fileinrbmode (FURB101) (#10803) - [
pylint] Don't recommend decorating staticmethods with@singledispatch(PLE1519,PLE1520) (#10637) - [
pydocstyle] Use section name range for all section-related docstring diagnostics (#10740) - Respect
# noqadirectives on__all__openers (#10798)
0.3.5
Preview features
- [
pylint] Implementmodified-iterating-set(E4703) (#10473) - [
refurb] Implementfor-loop-set-mutations(FURB142) (#10583) - [
refurb] Implementunnecessary-from-float(FURB164) (#10647) - [
refurb] Implementverbose-decimal-constructor(FURB157) (#10533)
Rule changes
- [
flake8-comprehensions] Handled special case forC401which also matchesC416(#10596) - [
flake8-pyi] Markunaliased-collections-abc-set-importfix as "safe" for more cases in stub files (PYI025) (#10547) - [
numpy] Addrow_stackto NumPy 2.0 migration rule (#10646) - [
pycodestyle] Allow cell magics before an import (E402) (#10545) - [
pycodestyle] Avoid blank line rules for the first logical line in cell (#10291)
Configuration
- Respected nested namespace packages (#10541)
- [
flake8-boolean-trap] Add setting for user defined allowed boolean trap (#10531)
Bug fixes
- Correctly handle references in
__all__definitions when renaming symbols in autofixes (#10527) - Track ranges of names inside
__all__definitions (#10525) - [
flake8-bugbear] Avoid false positive for usage aftercontinue(B031) (#10539) - [
flake8-copyright] Accept commas in default copyright pattern (#9498) - [
flake8-datetimez] Allow f-strings with%zforDTZ007(#10651) - [
flake8-pytest-style] FixPT014autofix for last item in list (#10532) - [
flake8-quotes] IgnoreQ000,Q001when string is inside forward ref (#10585) - [
isort] Always place non-relative imports after relative imports (#10669) - [
isort] Respect Unicode characters in import sorting (#10529) - [
pyflakes] Fix F821 false negatives whenfrom __future__ import annotationsis active (attempt 2) (#10524) - [
pyflakes] Makeunnecessary-lambdaan always-unsafe fix (#10668) - [
pylint] Fixed false-positive on the rulePLW1641(eq-without-hash) (#10566) - [
ruff] Fix panic in unused# noqaremoval with multi-byte space (RUF100) (#10682)
Documentation
- Add PR title format to
CONTRIBUTING.md(#10665) - Fix list markup to include blank lines required (#10591)
- Put
flake8-loggingnext to the other flake8 plugins in registry (#10587) - [
flake8-bandit] Update warning message for ruleS305to address insecure block cipher mode use (#10602) - [
flake8-bugbear] Document use of anonymous assignment inuseless-expression(#10551) - [
flake8-datetimez] Clarify error messages and docs forDTZrules (#10621) - [
pycodestyle] Use same before vs. after numbers forspace-around-operator(#10640) - [
ruff] Changequadratic-list-summationdocs to useiaddconsistently (#10666)
0.3.4
Preview features
- [
flake8-simplify] Detect implicitelsecases inneedless-bool(SIM103) (#10414) - [
pylint] Implementnan-comparison(PLW0117) (#10401) - [
pylint] Implementnonlocal-and-global(E115) (#10407) - [
pylint] Implementsingledispatchmethod-function(PLE5120) (#10428) - [
refurb] Implementlist-reverse-copy(FURB187) (#10212)
Rule changes
- [
flake8-pytest-style] Add automatic fix forpytest-parametrize-values-wrong-type(PT007) (#10461) - [
pycodestyle] Allow SPDX license headers to exceed the line length (E501) (#10481)
Formatter
- Fix unstable formatting for trailing subscript end-of-line comment (#10492)
Bug fixes
- Avoid code comment detection in PEP 723 script tags (#10464)
- Avoid incorrect tuple transformation in single-element case (
C409) (#10491) - Bug fix: Prevent fully defined links
namefrom being reformatted (#10442) - Consider raw source code for
W605(#10480) - Docs: Link inline settings when not part of options section (#10499)
- Don't treat annotations as redefinitions in
.pyifiles (#10512) - Fix
E231bug: Inconsistent catch compared to pycodestyle, such as when dict nested in list (#10469) - Fix pylint upstream categories not showing in docs (#10441)
- Add missing
Optionsreferences to blank line docs (#10498) - 'Revert "F821: Fix false negatives in .py files when
from __future__ import annotationsis active (#10362)"' (#10513) - Apply NFKC normalization to unicode identifiers in the lexer (#10412)
- Avoid failures due to non-deterministic binding ordering (#10478)
- [
flake8-bugbear] Allow tuples of exceptions (B030) (#10437) - [
flake8-quotes] Avoid syntax errors due to invalid quotes (Q000, Q002) (#10199)
0.3.3
Preview features
- [
flake8-bandit]: ImplementS610rule (#10316) - [
pycodestyle] Implementblank-line-at-end-of-file(W391) (#10243) - [
pycodestyle] Implementredundant-backslash(E502) (#10292) - [
pylint] - implementredeclared-assigned-name(W0128) (#9268)
Rule changes
- [
flake8_comprehensions] Handled special case forC400which also matchesC416(#10419) - [
flake8-bandit] Implement upstream updates forS311,S324andS605(#10313) - [
pyflakes] RemoveF401fix for__init__imports by default and allow opt-in to unsafe fix (#10365) - [
pylint] Implementinvalid-bool-return-type(E304) (#10377) - [
pylint] Include builtin warnings in useless-exception-statement (PLW0133) (#10394)
CLI
- Add message on success to
ruff check(#8631)
Bug fixes
- [
PIE970] Allow trailing ellipsis intyping.TYPE_CHECKING(#10413) - Avoid
TRIO115if the argument is a variable (#10376) - [
F811] Avoid removing shadowed imports that point to different symbols (#10387) - Fix
F821andF822false positives in.pyifiles (#10341) - Fix
F821false negatives in.pyfiles whenfrom __future__ import annotationsis active (#10362) - Fix case where
Indexerfails to identify continuation preceded by newline #10351 (#10354) - Sort hash maps in
Settingsdisplay (#10370) - Track conditional deletions in the semantic model (#10415)
- [
C413] Wrap expressions in parentheses when negating (#10346) - [
pycodestyle] Do not ignore lines before the first logical line in blank lines rules. (#10382) - [
pycodestyle] Do not triggerE225andE275when the next token is a ')' (#10315) - [
pylint] Avoid false-positive slot non-assignment for__dict__(PLE0237) (#10348) - Gate f-string struct size test for Rustc < 1.76 (#10371)
Documentation
- Use
ruff.tomlformat in README (#10393) - [
RUF008] Make it clearer that a mutable default in a dataclass is only valid if it is typed as a ClassVar (#10395) - [
pylint] Extend docs and test ininvalid-str-return-type(E307) (#10400) - Remove
.fromcheckandformatcommands (#10217)
0.3.2
Preview features
- Improve single-
withitem formatting for Python 3.8 or older (#10276)
Rule changes
- [
pyupgrade] Allow fixes for f-string rule regardless of line length (UP032) (#10263) - [
pycodestyle] Include actual conditions in E712 diagnostics (#10254)
Bug fixes
- Fix trailing kwargs end of line comment after slash (#10297)
- Fix unstable
withitems formatting (#10274) - Avoid repeating function calls in f-string conversions (#10265)
- Fix E203 false positive for slices in format strings (#10280)
- Fix incorrect
Parameterrange for*argsand**kwargs(#10283) - Treat
typing.Annotatedsubscripts as type definitions (#10285)
0.3.1
Preview features
- [
pycodestyle] Fix E301 not triggering on decorated methods. (#10117) - [
pycodestyle] Respectisortsettings in blank line rules (E3*) (#10096) - [
pycodestyle] Make blank lines in typing stub files optional (E3*) (#10098) - [
pylint] Implementsingledispatch-method(E1519) (#10140) - [
pylint] Implementuseless-exception-statement(W0133) (#10176)
Rule changes
- [
flake8-debugger] Check for use ofdebugpyandptvsddebug modules (#10177) (#10194) - [
pyupgrade] Generate diagnostic for all valid f-string conversions regardless of line length (UP032) (#10238) - [
pep8_naming] Add fixes forN804andN805(#10215)
CLI
- Colorize the output of
ruff format --diff(#10110) - Make
--configand--isolatedglobal flags (#10150) - Correctly expand tildes and environment variables in paths passed to
--config(#10219)
Configuration
- Accept a PEP 440 version specifier for
required-version(#10216) - Implement isort's
default-sectionsetting (#10149)
Bug fixes
- Remove trailing space from
CapWordsmessage (#10220) - Respect external codes in file-level exemptions (#10203)
- [
flake8-raise] Avoid false-positives for parens-on-raise withfuture.exception()(RSE102) (#10206) - [
pylint] Add fix for unary expressions inPLC2801(#9587) - [
ruff] Fix RUF028 not allowing# fmt: skipon match cases (#10178)
0.3.0
This release introduces the new Ruff formatter 2024.2 style and adds a new lint rule to detect invalid formatter suppression comments.
Preview features
- [
flake8-bandit] Remove suspicious-lxml-import (S410) (#10154) - [
pycodestyle] Allowos.environmodifications between imports (E402) (#10066) - [
pycodestyle] Don't warn about a single whitespace character before a comma in a tuple (E203) (#10094)
Rule changes
- [
eradicate] Detect commented outcasestatements (ERA001) (#10055) - [
eradicate] Detect single-line code fortry:,except:, etc. (ERA001) (#10057) - [
flake8-boolean-trap] Allow boolean positionals in__post_init__(#10027) - [
flake8-copyright] Allow © in copyright notices (#10065) - [
isort]: Use one blank line after imports in typing stub files (#9971) - [
pylint] New Ruledict-iter-missing-items(PLE1141) (#9845) - [
pylint] Ignoresys.versionandsys.platform(PLR1714) (#10054) - [
pyupgrade] Detect literals with unary operators (UP018) (#10060) - [
ruff] Expand rule forlist(iterable).pop(0)idiom (RUF015) (#10148)
Formatter
This release introduces the Ruff 2024.2 style, stabilizing the following changes:
- Prefer splitting the assignment's value over the target or type annotation (#8943)
- Remove blank lines before class docstrings (#9154)
- Wrap multiple context managers in
withparentheses when targeting Python 3.9 or newer (#9222) - Add a blank line after nested classes with a dummy body (
...) in typing stub files (#9155) - Reduce vertical spacing for classes and functions with a dummy (
...) body (#7440, #9240) - Add a blank line after the module docstring (#8283)
- Parenthesize long type hints in assignments (#9210)
- Preserve indent for single multiline-string call-expressions (#9673)
- Normalize hex escape and unicode escape sequences (#9280)
- Format module docstrings (#9725)
CLI
- Explicitly disallow
extendas part of a--configflag (#10135) - Remove
buildfrom the default exclusion list (#10093) - Deprecate
ruff <path>,ruff --explain,ruff --clean, andruff --generate-shell-completionin favor ofruff check <path>,ruff rule,ruff clean, andruff generate-shell-completion(#10169) - Remove the deprecated CLI option
--formatfromruff ruleandruff linter(#10170)
Bug fixes
- [
flake8-bugbear] Avoid adding default initializers to stubs (B006) (#10152) - [
flake8-type-checking] Respect runtime-required decorators for function signatures (#10091) - [
pycodestyle] Mark fixes overlapping with a multiline string as unsafe (W293) (#10049) - [
pydocstyle] Trim whitespace when removing blank lines after section (D413) (#10162) - [
pylint] Delete entire statement, including semicolons (PLR0203) (#10074) - [
ruff] Avoid f-string false positives ingettextcalls (RUF027) (#10118) - Fix
ruffcrashing on PowerPC systems because of too small page size (#10080)
Performance
- Add cold attribute to less likely printer queue branches in the formatter (#10121)
- Skip unnecessary string normalization in the formatter (#10116)
Documentation
- Remove "Beta" Label from formatter documentation (#10144)
line-lengthoption: fix link topycodestyle.max-line-length(#10136)
0.2.2
Highlights include:
- Initial support formatting f-strings (in
--preview). - Support for overriding arbitrary configuration options via the CLI through an expanded
--configargument (e.g.,--config "lint.isort.combine-as-imports=false"). - Significant performance improvements in Ruff's lexer, parser, and lint rules.
Preview features
- Implement minimal f-string formatting (#9642)
- [
pycodestyle] Add blank line(s) rules (E301,E302,E303,E304,E305,E306) (#9266) - [
refurb] Implementreadlines_in_for(FURB129) (#9880)
Rule changes
- [
ruff] Ensure closing parentheses for multiline sequences are always on their own line (RUF022,RUF023) (#9793) - [
numpy] Add missing deprecation violations (NPY002) (#9862) - [
flake8-bandit] Detectmark_safeusages in decorators (#9887) - [
ruff] Expandasyncio-dangling-task(RUF006) to includenew_event_loop(#9976) - [
flake8-pyi] Ignore 'unused' private type dicts in class scopes (#9952)
Formatter
- Docstring formatting: Preserve tab indentation when using
indent-style=tabs(#9915) - Disable top-level docstring formatting for notebooks (#9957)
- Stabilize quote-style's
preservemode (#9922)
CLI
- Allow arbitrary configuration options to be overridden via the CLI (#9599)
Bug fixes
- Make
show-settingsfilters directory-agnostic (#9866) - Respect duplicates when rewriting type aliases (#9905)
- Respect tuple assignments in typing analyzer (#9969)
- Use atomic write when persisting cache (#9981)
- Use non-parenthesized range for
DebugText(#9953) - [
flake8-simplify] Avoid false positive withasyncfor loops (SIM113) (#9996) - [
flake8-trio] Respectasync withintimeout-without-await(#9859) - [
perflint] Catch a wider range of mutations inPERF101(#9955) - [
pycodestyle] FixE30Xpanics on blank lines with trailing white spaces (#9907) - [
pydocstyle] Allow usingparametersas a subsection header (D405) (#9894) - [
pydocstyle] Fix blank-line docstring rules for module-level docstrings (#9878) - [
pylint] Accept 0.0 and 1.0 as common magic values (PLR2004) (#9964) - [
pylint] Avoid suggesting set rewrites for non-hashable types (#9956) - [
ruff] Avoid false negatives with string literals inside of method calls (RUF027) (#9865) - [
ruff] Fix panic on with f-string detection (RUF027) (#9990) - [
ruff] Ignore builtins when detecting missing f-strings (#9849)
Performance
- Use
memchrfor string lexing (#9888) - Use
memchrfor tab-indentation detection (#9853) - Reduce
Result<Tok, LexicalError>size by usingBox<str>instead ofString(#9885) - Reduce size of
Exprfrom 80 to 64 bytes (#9900) - Improve trailing comma rule performance (#9867)
- Remove unnecessary string cloning from the parser (#9884)
0.2.1
This release includes support for range formatting (i.e., the ability to format specific lines within a source file).
Preview features
Formatter
Bug fixes
- Skip empty lines when determining base indentation (#9795)
- Drop
__get__and__set__fromunnecessary-dunder-call(#9791) - Respect generic
Protocolin ellipsis removal (#9841) - Revert "Use publicly available Apple Silicon runners (#9726)" (#9834)
Performance
- Skip LibCST parsing for standard dedent adjustments (#9769)
- Remove CST-based fixer for
C408(#9822) - Add our own ignored-names abstractions (#9802)
- Remove CST-based fixers for
C400,C401,C410, andC418(#9819) - Use
AhoCorasickto speed up quote match (#9773) - Remove CST-based fixers for
C405andC409(#9821) - Add fast-path for comment detection (#9808)
- Invert order of checks in
zero-sleep-call(#9766) - Short-circuit typing matches based on imports (#9800)
- Run dunder method rule on methods directly (#9815)
- Track top-level module imports in the semantic model (#9775)
- Slight speed-up for lowercase and uppercase identifier checks (#9798)
- Remove LibCST-based fixer for
C403(#9818)
Documentation
- Update
max-pos-argsexample tomax-positional-args(#9797) - Fixed example code in
weak_cryptographic_key.rs(#9774) - Fix references to deprecated
ANNrules in changelog (#9771) - Fix default for
max-positional-args(#9838)
0.2.0
Breaking changes
- The
NURSERYselector cannot be used anymore - Legacy selection of nursery rules by exact codes is no longer allowed without preview enabled
See also, the "Remapped rules" section which may result in disabled rules.
Deprecations
The following rules are now deprecated:
missing-type-self(ANN101)missing-type-cls(ANN102)
The following command line options are now deprecated:
--show-source; use--output-format fullinstead--no-show-source; use--output-format conciseinstead--output-format text; usefullorconciseinstead
The following settings have moved and the previous name is deprecated:
ruff.allowed-confusables→ruff.lint.allowed-confusablesruff.dummy-variable-rgx→ruff.lint.dummy-variable-rgxruff.explicit-preview-rules→ruff.lint.explicit-preview-rulesruff.extend-fixable→ruff.lint.extend-fixableruff.extend-ignore→ruff.lint.extend-ignoreruff.extend-per-file-ignores→ruff.lint.extend-per-file-ignoresruff.extend-safe-fixes→ruff.lint.extend-safe-fixesruff.extend-select→ruff.lint.extend-selectruff.extend-unfixable→ruff.lint.extend-unfixableruff.extend-unsafe-fixes→ruff.lint.extend-unsafe-fixesruff.external→ruff.lint.externalruff.fixable→ruff.lint.fixableruff.flake8-annotations→ruff.lint.flake8-annotationsruff.flake8-bandit→ruff.lint.flake8-banditruff.flake8-bugbear→ruff.lint.flake8-bugbearruff.flake8-builtins→ruff.lint.flake8-builtinsruff.flake8-comprehensions→ruff.lint.flake8-comprehensionsruff.flake8-copyright→ruff.lint.flake8-copyrightruff.flake8-errmsg→ruff.lint.flake8-errmsgruff.flake8-gettext→ruff.lint.flake8-gettextruff.flake8-implicit-str-concat→ruff.lint.flake8-implicit-str-concatruff.flake8-import-conventions→ruff.lint.flake8-import-conventionsruff.flake8-pytest-style→ruff.lint.flake8-pytest-styleruff.flake8-quotes→ruff.lint.flake8-quotesruff.flake8-self→ruff.lint.flake8-selfruff.flake8-tidy-imports→ruff.lint.flake8-tidy-importsruff.flake8-type-checking→ruff.lint.flake8-type-checkingruff.flake8-unused-arguments→ruff.lint.flake8-unused-argumentsruff.ignore→ruff.lint.ignoreruff.ignore-init-module-imports→ruff.lint.ignore-init-module-importsruff.isort→ruff.lint.isortruff.logger-objects→ruff.lint.logger-objectsruff.mccabe→ruff.lint.mccaberuff.pep8-naming→ruff.lint.pep8-namingruff.per-file-ignores→ruff.lint.per-file-ignoresruff.pycodestyle→ruff.lint.pycodestyleruff.pydocstyle→ruff.lint.pydocstyleruff.pyflakes→ruff.lint.pyflakesruff.pylint→ruff.lint.pylintruff.pyupgrade→ruff.lint.pyupgraderuff.select→ruff.lint.selectruff.task-tags→ruff.lint.task-tagsruff.typing-modules→ruff.lint.typing-modulesruff.unfixable→ruff.lint.unfixable
Remapped rules
The following rules have been remapped to new codes:
raise-without-from-inside-except:TRY200toB904suspicious-eval-usage:PGH001toS307logging-warn:PGH002toG010static-key-dict-comprehension:RUF011toB035runtime-string-union:TCH006toTCH010
Stabilizations
The following rules have been stabilized and are no longer in preview:
trio-timeout-without-await(TRIO100)trio-sync-call(TRIO105)trio-async-function-with-timeout(TRIO109)trio-unneeded-sleep(TRIO110)trio-zero-sleep-call(TRIO115)unnecessary-escaped-quote(Q004)enumerate-for-loop(SIM113)zip-dict-keys-and-values(SIM911)timeout-error-alias(UP041)flask-debug-true(S201)tarfile-unsafe-members(S202)ssl-insecure-version(S502)ssl-with-bad-defaults(S503)ssl-with-no-version(S504)weak-cryptographic-key(S505)ssh-no-host-key-verification(S507)django-raw-sql(S611)mako-templates(S702)generator-return-from-iter-method(PYI058)runtime-string-union(TCH006)numpy2-deprecation(NPY201)quadratic-list-summation(RUF017)assignment-in-assert(RUF018)unnecessary-key-check(RUF019)never-union(RUF020)direct-logger-instantiation(LOG001)invalid-get-logger-argument(LOG002)exception-without-exc-info(LOG007)undocumented-warn(LOG009)
Fixes for the following rules have been stabilized and are now available without preview:
triple-single-quotes(D300)non-pep604-annotation(UP007)dict-get-with-none-default(SIM910)in-dict-keys(SIM118)collapsible-else-if(PLR5501)if-with-same-arms(SIM114)useless-else-on-loop(PLW0120)unnecessary-literal-union(PYI030)unnecessary-spread(PIE800)error-instead-of-exception(TRY400)redefined-while-unused(F811)duplicate-value(B033)multiple-imports-on-one-line(E401)non-pep585-annotation(UP006)
Fixes for the following rules have been promoted from unsafe to safe:
unaliased-collections-abc-set-import(PYI025)
The following behaviors have been stabilized:
module-import-not-at-top-of-file(E402) allowssys.pathmodifications between importsreimplemented-container-builtin(PIE807) includes lambdas that can be replaced withdictunnecessary-placeholder(PIE790) applies to unnecessary ellipses (...)if-else-block-instead-of-dict-get(SIM401) applies toif-elseexpressions
Preview features
- [
refurb] Implementmetaclass_abcmeta(FURB180) (#9658) - Implement
blank_line_after_nested_stub_classpreview style (#9155) - The preview rule
and-or-ternary(PLR1706) was removed
Bug fixes
- [
flake8-async] Takepathlib.Pathinto account when analyzing async functions (#9703) - [
flake8-return] - fix indentation syntax error (RET505) (#9705) - Detect multi-statement lines in else removal (#9748)
RUF022,RUF023: never add two trailing commas to the end of a sequence (#9698)RUF023: Don't sort__match_args__, only__slots__(#9724)- [
flake8-simplify] - Fix syntax error in autofix (SIM114) (#9704) - [
pylint] Show verbatim constant inmagic-value-comparison(PLR2004) (#9694) - Removing trailing whitespace inside multiline strings is unsafe (#9744)
- Support
IfExpwith dual string arms ininvalid-envvar-default(#9734) - [
pylint] Add__mro_entries__to known dunder methods (PLW3201) (#9706)
Documentation
- Removed rules are now retained in the documentation (#9691)
- Deprecated rules are now indicated in the documentation (#9689)
0.1.15
Preview features
- Error when
NURSERYselector is used with--preview(#9682) - Preserve indentation around multiline strings in formatter (#9637)
- [
flake8-return] Add fixes for all rules (RET505,RET506,RET507,RET508) (#9595) - [
flake8-simplify] Add fix forif-with-same-arms(SIM114) (#9591) - [
pycodestyle] Add fix formultiple-imports-on-one-line(E401) (#9518) - [
pylint] Add fix forcollapsible-else-if(PLR5501) (#9594) - [
pylint] Add fix foruseless-else-on-loop(PLW0120) (#9590) - [
pylint] Implementassigning-non-slot(E0237) (#9623) - [
pylint] Implementpotential-index-error(PLE0643) (#9545) - [
pylint] Implementtoo-many-nested-blocks(PLR1702) (#9172) - [
ruff] Add rule to sort__slots__and__match_args__(#9564) - [
ruff] Detect unnecessarydictcomprehensions for iterables (RUF025) (#9613) - [
ruff] Guard against use ofdefault_factoryas a keyword argument (RUF026) (#9651) - [
ruff] Implementmutable-fromkeys-value(RUF024) (#9597)
CLI
- Enable auto-wrapping of
--helpoutput (#9633)
Bug fixes
- Avoid rendering display-only rules as fixable (#9649)
- Detect automagic-like assignments in notebooks (#9653)
- Generate custom JSON schema for dynamic setting (#9632)
- [
flake8-no-pep420] Include global--configwhen determining namespace packages (#9603) - [
flake8-pie] Omit bound tuples passed to.startswithor.endswith(#9661) - [
flake8-return] Avoid panic when fixing inlined else blocks (#9657) - [
flake8-return] Consider exception suppression in unnecessary assignment (#9673) - [
flake8-return] TakeNoReturnannotation into account when analyzing implicit returns (#9636) - [
flake8-simplify] Support inverted returns inneedless-bool(SIM103) (#9619) - [
flake8-type-checking] Add Pydantic'sBaseConfigto default-copy list (#9650) - [
flake8-type-checking] Avoid markingInitVaras a typing-only annotation (#9688) - [
pycodestyle] Allowdtypecomparisons intype-comparison(#9676) - [
pydocstyle] Re-implementlast-line-after-section(D413) (#9654)
Documentation
- [
flake8-pytest-style] Add fix safety documentation forduplicate-parameterize-test-cases(#9678) - [
pylint] Documentliteral-membershipfix safety conditions (#9677) - [
isort] Fix reference toisortrule code (#9598)
0.1.14
Preview features
- [
flake8-bugbear] Add fix forduplicate-value(B033) (#9510) - [
flake8-simplify] Implementenumerate-for-loop(SIM113) (#7777) - [
pygrep_hooks] Add fix fordeprecated-log-warn(PGH002) (#9519) - [
pylint] Implementimport-private-name(C2701) (#5920) - [
refurb] Implementregex-flag-aliaswith fix (FURB167) (#9516) - [
ruff] Add rule and fix to sort contents of__all__(RUF022) (#9474) - [
tryceratops] Add fix forerror-instead-of-exception(TRY400) (#9520)
Rule changes
- [
flake8-pyi] FixPYI047false negatives on PEP-695 type aliases (#9566) - [
flake8-pyi] FixPYI049false negatives on call-basedTypedDicts (#9567) - [
pylint] Excludeselfandclswhen counting method arguments (PLR0917) (#9563)
CLI
--show-settingsdisplays active settings in a far more readable format (#9464)- Add
--extensionsupport to the formatter (#9483)
Configuration
- Ignore preview status for fixable and unfixable selectors (#9538)
- [
pycodestyle] Use the configured tab size when expanding indents (#9506)
Bug fixes
- Recursively visit deferred AST nodes (#9541)
- Visit deferred lambdas before type definitions (#9540)
- [
flake8-simplify] Avoid some moreenumerate-for-loopfalse positives (SIM113) (#9515) - [
pandas-vet] Limit inplace diagnostics to methods that accept inplace (#9495) - [
pylint] Add the__prepare__method to the list of recognized dunder method (#9529) - [
pylint] Ignore unnecessary dunder calls within dunder definitions (#9496) - [
refurb] Avoid bailing whenreimplemented-operatoris called on function (FURB118) (#9556) - [
ruff] Avoid treating named expressions as static keys (RUF011) (#9494)
Documentation
- Add instructions on using
noqawith isort rules (#9555) - Documentation update for URL giving 'page not found' (#9565)
- Fix admonition in dark mode (#9502)
- Update contributing docs to use
cargo bench -p ruff_benchmark(#9535) - Update emacs integration section to include
emacs-ruff-format(#9403) - [
flake8-blind-except] Document exceptions toblind-exceptrule (#9580)
0.1.13
Bug fixes
- Include base pyproject when initializing cache settings (#9480)
- [
flake8-simplify] Account for possibly-empty f-string values in truthiness logic (#9484) - [
pylint] Add the missing period inunnecessary-dunder-call(#9485) - [
pylint] Fix__aenter__message inunnecessary-dunder-call(#9492)
0.1.12
Preview features
- Formatter: Hug multiline-strings in preview style (#9243)
- [
flake8-bandit] Addssl-with-no-version(S504) (#9384) - [
flake8-bandit] Implementssl-insecure-version(S502) (#9390) - [
flake8-bandit] Implementssl-with-bad-defaults(S503) (#9391) - [
flake8-bandit] Implement suspicious import rules (S4XX) (#8831) - [
flake8-simplify] Implementzip-dict-keys-and-values(SIM911) (#9460) - [
pyflakes] Add a fix forredefined-while-unused(F811) (#9419) - [
pylint] Implementunnecessary-dunder-call(C2801) (#9166) - [
ruff] Addparenthesize-chained-operators(RUF021) to enforce parentheses ina or b and c(#9440)
Rule changes
- [
flake8-boolean-trap] Allow Boolean positional arguments in setters (#9429) - [
flake8-builtins] Restrictbuiltin-attribute-shadowing(A003) to actual shadowed references (#9462) - [
flake8-pyi] Add fix forgenerator-return-from-iter-method(PYI058) (#9355) - [
pyflakes] Don't flagredefined-while-unused(F811) inifbranches (#9418) - [
pyupgrade] Add some additional Python 3.12 typing members todeprecated-import(#9445) - [
ruff] Add fix forparenthesize-chained-operators(RUF021) (#9449) - [
ruff] Include subscripts and attributes in static key rule (RUF011) (#9416) - [
ruff] Support variable keys in static dictionary key rule (RUF011) (#9411)
Formatter
- Generate deterministic IDs when formatting notebooks (#9359)
- Allow
# fmt: skipwith interspersed same-line comments (#9395) - Parenthesize breaking named expressions in match guards (#9396)
Bug fixes
- Add cell indexes to all diagnostics (#9387)
- Avoid infinite loop in constant vs.
Nonecomparisons (#9376) - Handle raises with implicit alternate branches (#9377)
- Ignore trailing quotes for unclosed l-brace errors (#9388)
- Respect multi-segment submodule imports when resolving qualified names (#9382)
- Use
DisplayParseErrorfor stdin parser errors (#9409) - Use
comment_rangesfor isort directive extraction (#9414) - Use transformed source code for diagnostic locations (#9408)
- [
flake8-pyi] Excludewarnings.deprecatedandtyping_extensions.deprecatedarguments (#9423) - [
flake8-pyi] Fix false negative forunused-private-protocol(PYI046) with unused generic protocols (#9405) - [
pydocstyle] Disambiguate argument descriptors from section headers (#9427) - [
pylint] HomogenizePLR0914message to match otherPLR09XXrules (#9399) - [
ruff] AllowHashable = Nonein type annotations (RUF013) (#9442)
Documentation
0.1.11
Preview features
- [
pylint] Implementsuper-without-brackets(W0245) (#9257)
Bug fixes
- Check path string properly in
python -m ruffinvocations (#9367)
Documentation
0.1.10
Preview features
- Improve
dummy_implementationspreview style formatting (#9240) - Normalise Hex and unicode escape sequences in strings (#9280)
- Parenthesize long type annotations in annotated assignments (#9210)
- Parenthesize multi-context managers in
withstatements (#9222) - [
flake8-pyi] Implementgenerator-return-from-iter-method(PYI058) (#9313) - [
pylint] Implementempty-comment(PLR2044) (#9174) - [
refurb] Implementbit-count(FURB161) (#9265) - [
ruff] Addnever-unionrule to detect redundanttyping.NoReturnandtyping.Never(#9217)
CLI
- Add paths to TOML parse errors (#9358)
- Add row and column numbers to formatter parse errors (#9321)
- Improve responsiveness when invoked via Python (#9315)
- Short rule messages should not end with a period (#9345)
Configuration
- Respect runtime-required decorators on functions (#9317)
Bug fixes
- Avoid
asyncio-dangling-taskfor nonlocal and global bindings (#9263) - Escape trailing placeholders in rule documentation (#9301)
- Fix continuation detection following multi-line strings (#9332)
- Fix scoping for generators in named expressions in classes (#9248)
- Port from obsolete wsl crate to is-wsl (#9356)
- Remove special pre-visit for module docstrings (#9261)
- Respect
__str__definitions from super classes (#9338) - Respect
unused-noqaviaper-file-ignores(#9300) - Respect attribute chains when resolving builtin call paths (#9309)
- Treat all
typing_extensionsmembers as typing aliases (#9335) - Use
Displayfor formatter parse errors (#9316) - Wrap subscripted dicts in parens for f-string conversion (#9238)
- [
flake8-annotations] Avoid adding return types to stub methods (#9277) - [
flake8-annotations] Respect mixedreturnandraisecases in return-type analysis (#9310) - [
flake8-bandit] Don't report violations whenSafeLoaderis imported fromyaml.loader(S506) (#9299) - [
pylint] Avoid panic when comment is preceded by Unicode (#9331) - [
pylint] ChangePLR0917error message to match otherPLR09XXmessages (#9308) - [
refurb] Avoid false positives formath-constant(FURB152) (#9290)
Documentation
- Expand target name for better rule documentation (#9302)
- Fix typos found by codespell (#9346)
- [
perflint] DocumentPERF102fix un-safety (#9351) - [
pyupgrade] DocumentUP007fix un-safety (#9306)
0.1.9
Breaking changes
- Add site-packages to default exclusions (#9188)
Preview features
- Fix: Avoid parenthesizing subscript targets and values (#9209)
- [
pylint] Implementtoo-many-locals(PLR0914) (#9163) - Implement
reimplemented_operator(FURB118) (#9171) - Add a rule to detect string members in runtime-evaluated unions (#9143)
- Implement
no_blank_line_before_class_docstringpreview style (#9154)
Rule changes
CONSTANT_CASEvariables are improperly flagged for yoda violation (SIM300) (#9164)- [
flake8-pyi] Cover ParamSpecs and TypeVarTuples (PYI018) (#9198) - [
flake8-bugbear] Add fix forzip-without-explicit-strict(B905) (#9176) - Add fix to automatically remove
printandpprintstatements (T201,T203) (#9208) - Prefer
NevertoNoReturnin auto-typing in Python >= 3.11 (ANN201) (#9213)
Formatter
can_omit_optional_parentheses: Exit early for unparenthesized expressions (#9125)- Fix
dynamicmode with doctests so that it doesn't exceed configured line width (#9129) - Fix
can_omit_optional_parenthesesfor expressions with a right most fstring (#9124) - Add
target_versionto formatter options (#9220)
CLI
- Update
ruff format --checkto display message for already formatted files (#9153)
Bug fixes
- Reverse order of arguments for
operator.contains(#9192) - Iterate over lambdas in deferred type annotations (#9175)
- Fix panic in
D208with multibyte indent (#9147) - Add support for
NoReturnin auto-return-typing (#9206) - Allow removal of
typingfromexempt-modules(#9214) - Avoid
mutable-class-defaultviolations for Pydantic subclasses (#9187) - Fix dropped union expressions for piped non-types in
PYI055autofix (#9161) - Enable annotation quoting for multi-line expressions (#9142)
- Deduplicate edits when quoting annotations (#9140)
- Prevent invalid utf8 indexing in cell magic detection (#9146)
- Avoid nested quotations in auto-quoting fix (#9168)
- Add base-class inheritance detection to flake8-django rules (#9151)
- Avoid
asyncio-dangling-taskviolations on shadowed bindings (#9215)
Documentation
- Fix blog post URL in changelog (#9119)
- Add error suppression hint for multi-line strings (#9205)
- Fix typo in SemanticModel.parent_expression docstring (#9167)
- Document link between import sorting and formatter (#9117)
0.1.8
This release includes opt-in support for formatting Python snippets within
docstrings via the docstring-code-format setting.
Check out the blog post for more details!
Preview features
- Add
"preserve"quote-style to mimic Black's skip-string-normalization (#8822) - Implement
prefer_splitting_right_hand_side_of_assignmentspreview style (#8943) - [
pycodestyle] Add fix forunexpected-spaces-around-keyword-parameter-equals(#9072) - [
pycodestyle] Add fix for comment-related whitespace rules (#9075) - [
pycodestyle] Allowsys.pathmodifications between imports (#9047) - [
refurb] Implementhashlib-digest-hex(FURB181) (#9077)
Rule changes
- Allow
flake8-type-checkingrules to automatically quote runtime-evaluated references (#6001) - Allow transparent cell magics in Jupyter Notebooks (#8911)
- [
flake8-annotations] AvoidANN2xxfixes for abstract methods with empty bodies (#9034) - [
flake8-self] Ignore underscore references in type annotations (#9036) - [
pep8-naming] Allow class names whenapps.get_modelis a non-string (#9065) - [
pycodestyle] Allowmatplotlib.usecalls to intersperse imports (#9094) - [
pyflakes] Support fixing unused assignments in tuples by renaming variables (F841) (#9107) - [
pylint] Add fix forsubprocess-run-without-check(PLW1510) (#6708)
Formatter
- Add
docstring-code-formatknob to enable docstring snippet formatting (#8854) - Use double quotes for all docstrings, including single-quoted docstrings (#9020)
- Implement "dynamic" line width mode for docstring code formatting (#9098)
- Support reformatting Markdown code blocks (#9030)
- add support for formatting reStructuredText code snippets (#9003)
- Avoid trailing comma for single-argument with positional separator (#9076)
- Fix handling of trailing target comment (#9051)
CLI
- Hide unsafe fix suggestions when explicitly disabled (#9095)
- Add SARIF support to
--output-format(#9078)
Bug fixes
- Apply unnecessary index rule prior to enumerate rewrite (#9012)
- [
flake8-err-msg] AllowEMfixes even ifmsgvariable is defined (#9059) - [
flake8-pie] Prevent keyword arguments duplication (#8450) - [
flake8-pie] Respect trailing comma inunnecessary-dict-kwargs(PIE804) (#9015) - [
flake8-raise] Avoid removing parentheses on ctypes.WinError (#9027) - [
isort] Avoid invalid combination offorce-sort-within-typesandlines-between-types(#9041) - [
isort] Ensure that from-style imports are always ordered first in__future__(#9039) - [
pycodestyle] Allow tab indentation before keyword (#9099) - [
pylint] Ignore@overridesand@overloadsfortoo-many-positional(#9000) - [
pyupgrade] Enableprintf-string-formattingfix with comments on right-hand side (#9037) - [
refurb] Makemath-constant(FURB152) rule more targeted (#9054) - [
refurb] Support floating-point base inredundant-log-base(FURB163) (#9100) - [
ruff] Detectunused-asyncio-dangling-task(RUF006) on unused assignments (#9060)
0.1.7
Preview features
- Implement multiline dictionary and list hugging for preview style (#8293)
- Implement the
fix_power_op_line_lengthpreview style (#8947) - Use Python version to determine typing rewrite safety (#8919)
- [
flake8-annotations] Enable auto-return-type involvingOptionalandUnionannotations (#8885) - [
flake8-bandit] Implementdjango-raw-sql(S611) (#8651) - [
flake8-bandit] Implementtarfile-unsafe-members(S202) (#8829) - [
flake8-pyi] Implement fix forunnecessary-literal-union(PYI030) (#7934) - [
flake8-simplify] Extenddict-get-with-none-default(SIM910) to non-literals (#8762) - [
pylint] - addunnecessary-list-index-lookup(PLR1736) + autofix (#7999) - [
pylint] - implement R0202 and R0203 with autofixes (#8335) - [
pylint] Implementrepeated-keyword(PLe1132) (#8706) - [
pylint] Implementtoo-many-positional(PLR0917) (#8995) - [
pylint] Implementunnecessary-dict-index-lookup(PLR1733) (#8036) - [
refurb] Implementredundant-log-base(FURB163) (#8842)
Rule changes
- [
flake8-boolean-trap] Allow booleans in@overridemethods (#8882) - [
flake8-bugbear] AvoidB015,B018for last expression in a cell (#8815) - [
flake8-pie] Allow ellipses for enum values in stub files (#8825) - [
flake8-pyi] Check PEP 695 type aliases forsnake-case-type-aliasandt-suffixed-type-alias(#8966) - [
flake8-pyi] Check for kwarg and varargNoReturntype annotations (#8948) - [
flake8-simplify] Omit select context managers fromSIM117(#8801) - [
pep8-naming] Allow Django model loads innon-lowercase-variable-in-function(N806) (#8917) - [
pycodestyle] AvoidE703for last expression in a cell (#8821) - [
pycodestyle] UpdateE402to work at cell level for notebooks (#8872) - [
pydocstyle] AvoidD100for Jupyter Notebooks (#8816) - [
pylint] Implement fix forunspecified-encoding(PLW1514) (#8928)
Formatter
- Avoid unstable formatting in ellipsis-only body with trailing comment (#8984)
- Inline trailing comments for type alias similar to assignments (#8941)
- Insert trailing comma when function breaks with single argument (#8921)
CLI
- Update
ruff checkandruff formatto default to the current directory (#8791) - Stop at the first resolved parent configuration (#8864)
Configuration
- [
pylint] Defaultmax-positional-argstomax-args(#8998) - [
pylint] Addallow-dunder-method-namessetting forbad-dunder-method-name(PLW3201) (#8812) - [
isort] Add support forfrom-firstsetting (#8663) - [
isort] Add support forlength-sortsettings (#8841)
Bug fixes
- Add support for
@functools.singledispatch(#8934) - Avoid off-by-one error in stripping noqa following multi-byte char (#8979)
- Avoid off-by-one error in with-item named expressions (#8915)
- Avoid syntax error via invalid ur string prefix (#8971)
- Avoid underflow in
get_modelmatching (#8965) - Avoid unnecessary index diagnostics when value is modified (#8970)
- Convert over-indentation rule to use number of characters (#8983)
- Detect implicit returns in auto-return-types (#8952)
- Fix start >= end error in over-indentation (#8982)
- Ignore
@overloadand@overridemethods for too-many-arguments checks (#8954) - Lexer start of line is false only for
Mode::Expression(#8880) - Mark
pydantic_settings.BaseSettingsas having default copy semantics (#8793) - Respect dictionary unpacking in
NamedTupleassignments (#8810) - Respect local subclasses in
flake8-type-checking(#8768) - Support type alias statements in simple statement positions (#8916)
- [
flake8-annotations] Avoid filtering out un-representable types in return annotation (#8881) - [
flake8-pie] Retain extra ellipses in protocols and abstract methods (#8769) - [
flake8-pyi] Respect local enum subclasses insimple-defaults(PYI052) (#8767) - [
flake8-trio] Use correct range forTRIO115fix (#8933) - [
flake8-trio] Use full arguments range for zero-sleep-call (#8936) - [
isort] fix: mark__main__as first-party import (#8805) - [
pep8-naming] AvoidN806errors for type alias statements (#8785) - [
perflint] AvoidPERF101if there's an append in loop body (#8809) - [
pycodestyle] Allow space-before-colon after end-of-slice (#8838) - [
pydocstyle] Avoid non-character breaks inover-indentation(D208) (#8866) - [
pydocstyle] Ignore underlines when determining docstring logical lines (#8929) - [
pylint] Extendself-assigning-variableto multi-target assignments (#8839) - [
tryceratops] Avoid repeated triggers in nestedtryceratopsdiagnostics (#8772)
Documentation
- Add advice for fixing RUF008 when mutability is not desired (#8853)
- Added the command to run ruff using pkgx to the installation.md (#8955)
- Document fix safety for flake8-comprehensions and some pyupgrade rules (#8918)
- Fix doc formatting for zero-sleep-call (#8937)
- Remove duplicate imports from os-stat documentation (#8930)
- Replace generated reference to MkDocs (#8806)
- Update Arch Linux package URL in installation.md (#8802)
- [
flake8-pyi] Fix error int-suffixed-type-alias(PYI043) example (#8963) - [
flake8-pyi] Improve motivation forcustom-type-var-return-type(PYI019) (#8766)
0.1.6
Preview features
- [
flake8-boolean-trap] Extendboolean-type-hint-positional-argument(FBT001) to include booleans in unions (#7501) - [
flake8-pie] Extendreimplemented-list-builtin(PIE807) todictreimplementations (#8608) - [
flake8-pie] Extendunnecessary-pass(PIE790) to include ellipses (...) (#8641) - [
flake8-pie] Implement fix forunnecessary-spread(PIE800) (#8668) - [
flake8-quotes] Implementunnecessary-escaped-quote(Q004) (#8630) - [
pycodestyle] Implement fix formultiple-spaces-after-keyword(E271) andmultiple-spaces-before-keyword(E272) (#8622) - [
pycodestyle] Implement fix formultiple-spaces-after-operator(E222) andmultiple-spaces-before-operator(E221) (#8623) - [
pyflakes] Extendis-literal(F632) to include comparisons against mutable initializers (#8607) - [
pylint] Implementredefined-argument-from-local(PLR1704) (#8159) - [
pylint] Implement fix forunnecessary-lambda(PLW0108) (#8621) - [
refurb] Implementif-expr-min-max(FURB136) (#8664) - [
refurb] Implementmath-constant(FURB152) (#8727)
Rule changes
- [
flake8-annotations] Add autotyping-like return type inference for annotation rules (#8643) - [
flake8-future-annotations] Implement fix forfuture-required-type-annotation(FA102) (#8711) - [
flake8-implicit-namespace-package] Avoid missing namespace violations in scripts with shebangs (#8710) - [
pydocstyle] Updateover-indentation(D208) to preserve indentation offsets when fixing overindented lines (#8699) - [
pyupgrade] Refinetimeout-error-alias(UP041) to remove false positives (#8587)
Formatter
- Fix instability in
awaitformatting with fluent style (#8676) - Compare formatted and unformatted ASTs during formatter tests (#8624)
- Preserve trailing semicolon for Notebooks (#8590)
CLI
- Improve debug printing for resolving origin of config settings (#8729)
- Write unchanged, excluded files to stdout when read via stdin (#8596)
Configuration
- [
isort] Support disabling sections withno-sections = true(#8657) - [
pep8-naming] Support local and dynamic class- and static-method decorators (#8592) - [
pydocstyle] Allow overriding pydocstyle convention rules (#8586)
Bug fixes
- Avoid syntax error via importing
trio.lowlevel(#8730) - Omit unrolled augmented assignments in
PIE794(#8634) - Slice source code instead of generating it for
EMfixes (#7746) - Allow whitespace around colon in slices for
whitespace-before-punctuation(E203) (#8654) - Use function range for
no-self-use(#8637) - F-strings doesn't contain bytes literal for
PLW0129(#8675) - Improve detection of
TYPE_CHECKINGblocks imported fromtyping_extensionsor_typeshed(#8429) - Treat display as a builtin in IPython (#8707)
- Avoid
FURB113autofix if comments are present (#8494) - Consider the new f-string tokens for
flake8-commas(#8582) - Remove erroneous bad-dunder-name reference (#8742)
- Avoid recommending Self usages in metaclasses (#8639)
- Detect runtime-evaluated base classes defined in the current file (#8572)
- Avoid inserting trailing commas within f-strings (#8574)
- Remove incorrect deprecation label for stdout and stderr (#8743)
- Fix unnecessary parentheses in UP007 fix (#8610)
- Remove repeated and erroneous scoped settings headers in docs (#8670)
- Trim trailing empty strings when converting to f-strings (#8712)
- Fix ordering for
force-sort-within-sections(#8665) - Run unicode prefix rule over tokens (#8709)
- Update UP032 to unescape curly braces in literal parts of converted strings (#8697)
- List all ipython builtins (#8719)
Documentation
- Document conventions in the FAQ (#8638)
- Redirect from rule codes to rule pages in docs (#8636)
- Fix permalink to convention setting (#8575)
0.1.5
Preview features
- [
flake8-bandit] Implementmako-templates(S702) (#8533) - [
flake8-trio] ImplementTRIO105(#8490) - [
flake8-trio] ImplementTRIO109(#8534) - [
flake8-trio] ImplementTRIO110(#8537) - [
flake8-trio] ImplementTRIO115(#8486) - [
refurb] Implementtype-none-comparison(FURB169) (#8487) - Flag all comparisons against builtin types in
E721(#8491) - Make
SIM118fix as safe when the expression is a known dictionary (#8525)
Formatter
- Fix multiline lambda expression statement formatting (#8466)
CLI
- Add hidden
--extensionto override inference of source type from file extension (#8373)
Configuration
- Account for selector specificity when merging
extend_unsafe_fixesandoverride extend_safe_fixes(#8444) - Add support for disabling cache with
RUFF_NO_CACHEenvironment variable (#8538)
Bug fixes
- [
E721] Flag comparisons tomemoryview(#8485) - Allow collapsed-ellipsis bodies in other statements (#8499)
- Avoid
D301autofix foruprefixed strings (#8495) - Only flag
flake8-triorules whentrioimport is present (#8550) - Reject more syntactically invalid Python programs (#8524)
- Avoid raising
TRIO115violations fortrio.sleep(...)calls with non-number values (#8532) - Fix
F841false negative on assignment to multiple variables (#8489)
Documentation
- Fix link to isort
known-first-party(#8562) - Add notes on fix safety to a few rules (#8500)
- Add missing toml config tabs (#8512)
- Add instructions for configuration of Emacs (#8488)
- Improve detail link contrast in dark mode (#8548)
- Fix typo in example (#8506)
- Added tabs for configuration files in the documentation (#8480)
- Recommend
project.requires-pythonovertarget-version(#8513) - Add singleton escape hatch to
B008documentation (#8501) - Fix tab configuration docs (#8502)
0.1.4
Preview features
- [
flake8-trio] Implementtimeout-without-await(TRIO001) (#8439) - [
numpy] Implement NumPy 2.0 migration rule (NPY200) (#7702) - [
pylint] Implementbad-open-mode(W1501) (#8294) - [
pylint] Implementimport-outside-toplevel(C0415) rule (#5180) - [
pylint] Implementuseless-with-lock(W2101) (#8321) - [
pyupgrade] Implementtimeout-error-alias(UP041) (#8476) - [
refurb] Implementisinstance-type-none(FURB168) (#8308) - Detect confusable Unicode-to-Unicode units in
RUF001,RUF002, andRUF003(#4430) - Add newline after module docstrings in preview style (#8283)
Formatter
- Add a note on line-too-long to the formatter docs (#8314)
- Preserve trailing statement semicolons when using
fmt: skip(#8273) - Preserve trailing semicolons when using
fmt: off(#8275) - Avoid duplicating linter-formatter compatibility warnings (#8292)
- Avoid inserting a newline after function docstrings (#8375)
- Insert newline between docstring and following own line comment (#8216)
- Split tuples in return positions by comma first (#8280)
- Avoid treating byte strings as docstrings (#8350)
- Add
--line-lengthoption toformatcommand (#8363) - Avoid parenthesizing unsplittable because of comments (#8431)
CLI
- Add
--output-formattoruff ruleandruff linter(#8203)
Bug fixes
- Respect
--force-excludeinlint.excludeandformat.exclude(#8393) - Respect
--extend-per-file-ignoreson the CLI (#8329) - Extend
bad-dunder-method-nameto permit__index__(#8300) - Fix panic with 8 in octal escape (#8356)
- Avoid raising
D300when both triple quote styles are present (#8462) - Consider unterminated f-strings in
FStringRanges(#8154) - Avoid including literal
shell=Truefor truthy, non-Truediagnostics (#8359) - Avoid triggering single-element test for starred expressions (#8433)
- Detect and ignore Jupyter automagics (#8398)
- Fix invalid E231 error with f-strings (#8369)
- Avoid triggering
NamedTuplerewrite with starred annotation (#8434) - Avoid un-setting bracket flag in logical lines (#8380)
- Place 'r' prefix before 'f' for raw format strings (#8464)
- Remove trailing periods from NumPy 2.0 code actions (#8475)
- Fix bug where
PLE1307was raised when formatting%cwith characters (#8407) - Remove unicode flag from comparable (#8440)
- Improve B015 message (#8295)
- Use
fixedOverflowWidgetsfor playground popover (#8458) - Mark
byte_boundsas a non-backwards-compatible NumPy 2.0 change (#8474)
Internals
- Add a dedicated cache directory per Ruff version (#8333)
- Allow selective caching for
--fixand--diff(#8316) - Improve performance of comment parsing (#8193)
- Improve performance of string parsing (#8227)
- Use a dedicated sort key for isort import sorting (#7963)
0.1.3
This release includes a variety of improvements to the Ruff formatter, removing several known and unintentional deviations from Black.
Formatter
- Avoid space around pow for
None,TrueandFalse(#8189) - Avoid sorting all paths in the format command (#8181)
- Insert necessary blank line between class and leading comments (#8224)
- Avoid introducing new parentheses in annotated assignments (#8233)
- Refine the warnings about incompatible linter options (#8196)
- Add test and basic implementation for formatter preview mode (#8044)
- Refine warning about incompatible
isortsettings (#8192) - Only omit optional parentheses for starting or ending with parentheses (#8238)
- Use source type to determine parser mode for formatting (#8205)
- Don't warn about magic trailing comma when
isort.force-single-lineis true (#8244) - Use
SourceKind::difffor formatter (#8240) - Fix
fmt:offwith trailing child comment (#8234) - Formatter parentheses support for
IpyEscapeCommand(#8207)
Linter
- [
pylint] Add buffer methods tobad-dunder-method-name(PLW3201) exclusions (#8190) - Match rule prefixes from
externalcodes setting inunused-noqa(#8177) - Use
line-lengthsetting for isort in lieu ofpycodestyle.max-line-length(#8235) - Update fix for
unnecessary-paren-on-raise-exceptionto unsafe for unknown types (#8231) - Correct quick fix message for
W605(#8255)
Documentation
- Fix typo in max-doc-length documentation (#8201)
- Improve documentation around linter-formatter conflicts (#8257)
- Fix link to error suppression documentation in
unused-noqa(#8172) - Add
externaloption tounused-noqadocumentation (#8171) - Add title attribute to icons (#8060)
- Clarify unsafe case in RSE102 (#8256)
- Fix skipping formatting examples (#8210)
- docs: fix name of
magic-trailing-commaoption in README (#8200) - Add note about scope of rule changing in versioning policy (#8169)
- Document: Fix default lint rules (#8218)
- Fix a wrong setting in configuration.md (#8186)
- Fix misspelled TOML headers in the tutorial (#8209)
0.1.2
This release includes the Beta version of the Ruff formatter — an extremely fast, Black-compatible Python formatter.
Try it today with ruff format! Check out the blog post and read the docs.
Preview features
- [
pylint] Implementnon-ascii-module-import(C2403) (#8056) - [
pylint] implementnon-ascii-name(C2401) (#8038) - [
pylint] Implement unnecessary-lambda (W0108) (#7953) - [
refurb] Implementread-whole-file(FURB101) (#7682) - Add fix for
E223,E224, andE242(#8143) - Add fix for
E225,E226,E227, andE228(#8136) - Add fix for
E252(#8142) - Add fix for
E261(#8114) - Add fix for
E273andE274(#8144) - Add fix for
E275(#8133) - Update
SIM401to catch ternary operations (#7415) - Update
E721to allowisandisnot for direct type comparisons (#7905)
Rule changes
- Add
backports.strenumtodeprecated-imports(#8113) - Update
SIM112to ignorehttps_proxy,http_proxy, andno_proxy(#8140) - Update fix for
literal-membership(PLR6201) to be unsafe (#8097) - Update fix for
mutable-argument-defaults(B006) to be unsafe (#8108)
Formatter
- Change
line-endingdefault toauto(#8057) - Respect parenthesized generators in
has_own_parentheses(#8100) - Add caching to formatter (#8089)
- Remove
--line-lengthoption fromformatcommand (#8131) - Add formatter to
line-lengthdocumentation (#8150) - Warn about incompatible formatter options (#8088)
- Fix range of unparenthesized tuple subject in match statement (#8101)
- Remove experimental formatter warning (#8148)
- Don't move type param opening parenthesis comment (#8163)
- Update versions in format benchmark script (#8110)
- Avoid loading files for cached format results (#8134)
CLI
- Show the
ruff formatcommand in help menus (#8167) - Add
ruff versioncommand with long version display (#8034)
Configuration
- New
pycodestyle.max-line-lengthoption (#8039)
Bug fixes
- Detect
sys.version_infoslices inoutdated-version-block(#8112) - Avoid if-else simplification for
TYPE_CHECKINGblocks (#8072) - Avoid false-positive print separator diagnostic with starred argument (#8079)
Documentation
- Fix message for
too-many-argumentslint (#8092) - Fix
extend-unsafe-fixesandextend-safe-fixesexample (#8139) - Add links to
flake8-import-conventionsoptions (#8115) - Rework the documentation to incorporate the Ruff formatter (#7732)
- Fix
OptionsJSON schema description (#8081) - Fix typo (
pytext->pytest) (#8117) - Improve
magic-value-comparisonexample in docs (#8111)
0.1.1
Rule changes
- Add unsafe fix for
escape-sequence-in-docstring(D301) (#7970)
Configuration
- Respect
#(deprecated)attribute in configuration options (#8035) - Add
[format|lint].excludeoptions (#8000) - Respect
tab-sizesetting in formatter (#8006) - Add
lint.preview(#8002)
Preview features
- [
pylint] Implementliteral-membership(PLR6201) (#7973) - [
pylint] Implementtoo-many-boolean-expressions(PLR0916) (#7975) - [
pylint] Implementmisplaced-bare-raise(E0704) (#7961) - [
pylint] Implementglobal-at-module-level(W0604) (#8058) - [
pylint] Implementunspecified-encoding(PLW1514) (#7939) - Add fix for
triple-single-quotes(D300) (#7967)
Formatter
- New code style badge for
ruff format(#7878) - Fix comments outside expression parentheses (#7873)
- Add
--target-versiontoruff format(#8055) - Skip over parentheses when detecting
inkeyword (#8054) - Add
--diffoption toruff format(#7937) - Insert newline after nested function or class statements (#7946)
- Use
passover ellipsis in non-function/class contexts (#8049)
Bug fixes
- Lazily evaluate all PEP 695 type alias values (#8033)
- Avoid failed assertion when showing fixes from stdin (#8029)
- Avoid flagging HTTP and HTTPS literals in urllib-open (#8046)
- Avoid flagging
bad-dunder-method-namefor_(#8015) - Remove Python 2-only methods from
URLOpenaudit (#8047) - Use set bracket replacement for
iteration-over-setto preserve whitespace and comments (#8001)
Documentation
- Update tutorial to match revised Ruff defaults (#8066)
- Update rule
B005docs (#8028) - Update GitHub actions example in docs to use
--output-format(#8014) - Document
lint.previewandformat.preview(#8032) - Clarify that new rules should be added to
RuleGroup::Preview. (#7989)
0.1.0
This is the first release which uses the CHANGELOG file. See GitHub Releases for prior changelog entries.
Read Ruff's new versioning policy.
Breaking changes
- Unsafe fixes are no longer displayed or applied without opt-in (#7769)
- Drop formatting specific rules from the default set (#7900)
- The deprecated
formatsetting has been removed (#7984)- The
formatsetting cannot be used to configure the output format, useoutput-formatinstead - The
RUFF_FORMATenvironment variable is ignored, useRUFF_OUTPUT_FORMATinstead - The
--formatoption has been removed fromruff check, use--output-formatinstead
- The
Rule changes
- Extend
reimplemented-starmap(FURB140) to catch calls with a single and starred argument (#7768) - Improve cases covered by
RUF015(#7848) - Update
SIM15to allowopenfollowed byclose(#7916) - Respect
msgspec.Structdefault-copy semantics inRUF012(#7786) - Add
sqlalchemymethods to `flake8-boolean-trap`` exclusion list (#7874) - Add fix for
PLR1714(#7910) - Add fix for
PIE804(#7884) - Add fix for
PLC0208(#7887) - Add fix for
PYI055(#7886) - Update
non-pep695-type-aliasto require--unsafe-fixesoutside of stub files (#7836) - Improve fix message for
UP018(#7913) - Update
PLW3201to supportEnumsunder names (#7987)
Preview features
- Only show warnings for empty preview selectors when enabling rules (#7842)
- Add
unnecessary-key-checkto simplifykey in dct and dct[key]todct.get(key)(#7895) - Add
assignment-in-assertto prevent walrus expressions in assert statements (#7856) - [
refurb] Addsingle-item-membership-test(FURB171) (#7815) - [
pylint] Addand-or-ternary(R1706) (#7811)
New rules are added in preview.
Configuration
- Add
unsafe-fixessetting (#7769) - Add
extend-safe-fixesandextend-unsafe-fixesfor promoting and demoting fixes (#7841)
CLI
- Added
--unsafe-fixesoption for opt-in to display and apply unsafe fixes (#7769) - Fix use of deprecated
--formatoption in warning (#7837) - Show changed files when running under
--check(#7788) - Write summary messages to stderr when fixing via stdin instead of omitting them (#7838)
- Update fix summary message in
check --diffto include unsafe fix hints (#7790) - Add notebook
cellfield to JSON output format (#7664) - Rename applicability levels to
Safe,Unsafe, andDisplay(#7843)
Bug fixes
- Fix bug where f-strings were allowed in match pattern literal (#7857)
- Fix
SIM110with a yield in the condition (#7801) - Preserve trailing comments in
C414fixes (#7775) - Check sequence type before triggering
unnecessary-enumeratelensuggestion (#7781) - Use correct start location for class/function clause header (#7802)
- Fix incorrect fixes for
SIM101(#7798) - Format comment before parameter default correctly (#7870)
- Fix
E251false positive inside f-strings (#7894) - Allow bindings to be created and referenced within annotations (#7885)
- Show per-cell diffs when analyzing notebooks over
stdin(#7789) - Avoid curly brace escape in f-string format spec (#7780)
- Fix lexing single-quoted f-string with multi-line format spec (#7787)
- Consider nursery rules to be in-preview for
ruff rule(#7812) - Report precise location for invalid conversion flag (#7809)
- Visit pattern match guard as a boolean test (#7911)
- Respect
--unfixableinISCrules (#7917) - Fix edge case with
PIE804(#7922) - Show custom message in
PTH118forPath.joinpathwith starred arguments (#7852) - Fix false negative in
outdated-version-blockwhen using greater than comparisons (#7920) - Avoid converting f-strings within Django
gettextcalls (#7898) - Fix false positive in
PLR6301(#7933) - Treat type aliases as typing-only expressions e.g. resolves false positive in
TCH004(#7968) - Resolve
cache-dirrelative to project root (#7962) - Respect subscripted base classes in type-checking rules e.g. resolves false positive in
TCH003(#7954) - Fix JSON schema limit for
line-length(#7883) - Fix commented-out
coalescekeyword (#7876)
Documentation
- Document
reimplemented-starmapperformance effects (#7846) - Default to following the system dark/light mode (#7888)
- Add documentation for fixes (#7901)
- Fix typo in docs of
PLR6301(#7831) - Update
UP038docs to note that it results in slower code (#7872) - crlf -> cr-lf (#7766)
- Add an example of an unsafe fix (#7924)
- Fix documented examples for
unnecessary-subscript-reversal(#7774) - Correct error in tuple example in ruff formatter docs (#7822)
- Add versioning policy to documentation (#7923)
- Fix invalid code in
FURB177example (#7832)
Formatter
- Less scary
ruff formatmessage (#7867) - Remove spaces from import statements (#7859)
- Formatter quoting for f-strings with triple quotes (#7826)
- Update
ruff_python_formattergenerate.py comment (#7850) - Document one-call chaining deviation (#7767)
- Allow f-string modifications in line-shrinking cases (#7818)
- Add trailing comment deviation to README (#7827)
- Add trailing zero between dot and exponential (#7956)
- Force parentheses for power operations in unary expressions (#7955)
Playground
- Fix playground
Quick Fixaction (#7824)