Summary -- During the release today, I noticed that the changelog is finally too long to render at all on GitHub. This PR follows the same splitting procedure as in uv (astral-sh/uv#11510, astral-sh/uv#12099): first splitting the file into one per minor version, and then reversing the contents of each file to start with the breaking release (`changelogs/0.11.x.md` starts with 0.11.0 instead of 0.11.13 as in the old changelog). For the second part, I used [`reverse-changelog.py`](https://github.com/astral-sh/uv/blob/main/scripts/reverse-changelog.py) from the uv repo, so hopefully everything is correct. I spot-checked 0.7.0 at least.
24 KiB
Changelog 0.11.x
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.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.2
Preview features
- [syntax-errors] Fix false-positive syntax errors emitted for annotations on variadic parameters before Python 3.11 (#16878)
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.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.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 outdatedAIR301,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.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.7
Preview features
- [
airflow] Apply auto fixes to cases where the names have changed in Airflow 3 (AIR301) (#17355) - [
perflint] Implement fix formanual-dict-comprehension(PERF403) (#16719) - [syntax-errors] Make duplicate parameter names a semantic error (#17131)
Bug fixes
- [
airflow] Fix typos in provider package names (AIR302,AIR312) (#17574) - [
flake8-type-checking] Visit keyword arguments in checks involvingtyping.cast/typing.NewTypearguments (#17538) - [
pyupgrade] Preserve parenthesis when fixing native literals containing newlines (UP018) (#17220) - [
refurb] Mark theFURB161fix unsafe except for integers and booleans (#17240)
Rule changes
- [
perflint] Allow list function calls to be replaced with a comprehension (PERF401) (#17519) - [
pycodestyle] Auto-fix redundant boolean comparison (E712) (#17090) - [
pylint] make fix unsafe if delete comments (PLR1730) (#17459)
Documentation
0.11.8
Preview features
- [
airflow] Apply auto fixes to cases where the names have changed in Airflow 3 (AIR302,AIR311) (#17553, #17570, #17571) - [
airflow] ExtendAIR301rule (#17598) - [
airflow] Update existingAIR302rules with better suggestions (#17542) - [
refurb] Mark fix as safe forreadlines-in-for(FURB129) (#17644) - [syntax-errors]
nonlocaldeclaration at module level (#17559) - [syntax-errors] Detect single starred expression assignment
x = *y(#17624)
Bug fixes
- [
flake8-pyi] EnsureLiteral[None,] | Literal[None,]is not autofixed toNone | None(PYI061) (#17659) - [
flake8-use-pathlib] Avoid suggestingPath.iterdir()foros.listdirwith file descriptor (PTH208) (#17715) - [
flake8-use-pathlib] FixPTH104false positive whenrenameis passed a file descriptor (#17712) - [
flake8-use-pathlib] FixPTH116false positive whenstatis passed a file descriptor (#17709) - [
flake8-use-pathlib] FixPTH123false positive whenopenis passed a file descriptor from a function call (#17705) - [
pycodestyle] Fix duplicated diagnostic inE712(#17651) - [
pylint] Detectglobaldeclarations in module scope (PLE0118) (#17411) - [syntax-errors] Make
async-comprehension-in-sync-comprehensionmore specific (#17460)
Configuration
- Add option to disable
typing_extensionsimports (#17611)
Documentation
- Fix example syntax for the
lint.pydocstyle.ignore-var-parametersoption (#17740) - Add fix safety sections (
ASYNC116,FLY002,D200,RUF005,RUF017,RUF027,RUF028,RUF057) (#17497, #17496, #17502, #17484, #17480, #17485, #17722, #17483)
Other changes
- Add Python 3.14 to configuration options (#17647)
- Make syntax error for unparenthesized except tuples version specific to before 3.14 (#17660)
0.11.9
Preview features
- Default to latest supported Python version for version-related syntax errors (#17529)
- Implement deferred annotations for Python 3.14 (#17658)
- [
airflow] FixSQLTableCheckOperatortypo (AIR302) (#17946) - [
airflow] Removeairflow.utils.dag_parsing_context.get_parsing_context(AIR301) (#17852) - [
airflow] Skip attribute check in try catch block (AIR301) (#17790) - [
flake8-bandit] Mark tuples of string literals as trusted input inS603(#17801) - [
isort] Check full module path against project root(s) when categorizing first-party imports (#16565) - [
ruff] Add new rulein-empty-collection(RUF060) (#16480)
Bug fixes
- Fix missing
combinecall forlint.typing-extensionssetting (#17823) - [
flake8-async] Fix module name inASYNC110,ASYNC115, andASYNC116fixes (#17774) - [
pyupgrade] Add spaces between tokens as necessary to avoid syntax errors inUP018autofix (#17648) - [
refurb] Fix false positive for float and complex numbers inFURB116(#17661) - [parser] Flag single unparenthesized generator expr with trailing comma in arguments. (#17893)
Documentation
- Add instructions on how to upgrade to a newer Rust version (#17928)
- Update code of conduct email address (#17875)
- Add fix safety sections to
PLC2801,PLR1722, andRUF013(#17825, #17826, #17759) - Add link to
check-typed-exceptionfromS110andS112(#17786)
Other changes
- Allow passing a virtual environment to
ruff analyze graph(#17743)
0.11.10
Preview features
- [
ruff] Implement a recursive check forRUF060(#17976) - [
airflow] Enable autofixes forAIR301andAIR311(#17941) - [
airflow] Apply try catch guard to allAIR3rules (#17887) - [
airflow] ExtendAIR311rules (#17913)
Bug fixes
- [
flake8-bugbear] IgnoreB028ifskip_file_prefixesis present (#18047) - [
flake8-pie] Mark autofix forPIE804as unsafe if the dictionary contains comments (#18046) - [
flake8-simplify] Correct behavior forstr.split/rsplitwithmaxsplit=0(SIM905) (#18075) - [
flake8-simplify] FixSIM905autofix forrsplitcreating a reversed list literal (#18045) - [
flake8-use-pathlib] Suppress diagnostics for allos.*functions that have thedir_fdparameter (PTH) (#17968) - [
refurb] Mark autofix as safe only for number literals (FURB116) (#17692)
Rule changes
- [
flake8-bandit] SkipS608for expressionless f-strings (#17999) - [
flake8-pytest-style] Don't recommendusefixturesforparametrizevalues (PT019) (#17650) - [
pyupgrade] Addresource.erroras deprecated alias ofOSError(UP024) (#17933)
CLI
- Disable jemalloc on Android (#18033)
Documentation
- Update Neovim setup docs (#18108)
- [
flake8-simplify] Add fix safety section (SIM103) (#18086) - [
flake8-simplify] Add fix safety section (SIM112) (#18099) - [
pylint] Add fix safety section (PLC0414) (#17802) - [
pylint] Add fix safety section (PLE4703) (#17824) - [
pylint] Add fix safety section (PLW1514) (#17932) - [
pylint] Add fix safety section (PLW3301) (#17878) - [
ruff] Add fix safety section (RUF007) (#17755) - [
ruff] Add fix safety section (RUF033) (#17760)
0.11.11
Preview features
- [
airflow] Add autofixes forAIR302andAIR312(#17942) - [
airflow] Move rules fromAIR312toAIR302(#17940) - [
airflow] UpdateAIR301andAIR311with the latest Airflow implementations (#17985) - [
flake8-simplify] Enable fix in preview mode (SIM117) (#18208)
Bug fixes
- Fix inconsistent formatting of match-case on
[]and_(#18147) - [
pylint] FixPLW1514not recognizing theencodingpositional argument ofcodecs.open(#18109)
CLI
- Add full option name in formatter warning (#18217)
Documentation
- Fix rendering of admonition in docs (#18163)
- [
flake8-print] Improve print/pprint docs forT201andT203(#18130) - [
flake8-simplify] Add fix safety section (SIM110,SIM210) (#18114,#18100) - [
pylint] Fix docs example that produced different output (PLW0603) (#18216)
0.11.12
Preview features
- [
airflow] Revise fix titles (AIR3) (#18215) - [
pylint] Implementmissing-maxsplit-arg(PLC0207) (#17454) - [
pyupgrade] New ruleUP050(useless-class-metaclass-type) (#18334) - [
flake8-use-pathlib] Replaceos.symlinkwithPath.symlink_to(PTH211) (#18337)
Bug fixes
- [
flake8-bugbear] Ignore__debug__attribute inB010(#18357) - [
flake8-async] Fixanyio.sleepargument name (ASYNC115,ASYNC116) (#18262) - [
refurb] FixFURB129autofix generating invalid syntax (#18235)
Rule changes
- [
flake8-implicit-str-concat] Add autofix forISC003(#18256) - [
pycodestyle] Improve the diagnostic message forE712(#18328) - [
flake8-2020] Fix diagnostic message for!=comparisons (YTT201) (#18293) - [
pyupgrade] Make fix unsafe if it deletes comments (UP010) (#18291)
Documentation
- Simplify rules table to improve readability (#18297)
- Update editor integrations link in README (#17977)
- [
flake8-bugbear] Add fix safety section (B006) (#17652)
0.11.13
Preview features
- [
airflow] Add unsafe fix for module moved cases (AIR301,AIR311,AIR312,AIR302) (#18367,#18366,#18363,#18093) - [
refurb] Add coverage ofsetandfrozensetcalls (FURB171) (#18035) - [
refurb] MarkFURB180fix unsafe when class has bases (#18149)
Bug fixes
- [
perflint] Fix missing parentheses for lambda and ternary conditions (PERF401,PERF403) (#18412) - [
pyupgrade] ApplyUP035only on py313+ forget_type_hints()(#18476) - [
pyupgrade] Make fix unsafe if it deletes comments (UP004,UP050) (#18393, #18390)
Rule changes
- [
fastapi] Avoid false positive for class dependencies (FAST003) (#18271)
Documentation
- Update editor setup docs for Neovim and Vim (#18324)
Other changes
- Support Python 3.14 template strings (t-strings) in formatter and parser (#17851)