ruff/CHANGELOG.md

278 KiB
Raw Blame History

Changelog

0.11.8

Preview features

  • `airflow`
  • `airflow`
  • `airflow`
  • `refurb`
  • [syntax-errors] nonlocal declaration at module level (#17559)
  • [syntax-errors] Detect single starred expression assignment x = *y (#17624)

Bug fixes

  • `flake8-pyi`
  • `flake8-use-pathlib`
  • `flake8-use-pathlib`
  • `flake8-use-pathlib`
  • `flake8-use-pathlib`
  • `pycodestyle`
  • `pylint`
  • [syntax-errors] Make async-comprehension-in-sync-comprehension more specific (#17460)

Configuration

  • Add option to disable typing_extensions imports (#17611)

Documentation

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.7

Preview features

  • `airflow`
  • `perflint`
  • [syntax-errors] Make duplicate parameter names a semantic error (#17131)

Bug fixes

  • `airflow`
  • `flake8-type-checking`
  • `pyupgrade`
  • `refurb`

Rule changes

  • `perflint`
  • `pycodestyle`
  • `pylint`

Documentation

0.11.6

Preview features

  • Avoid adding whitespace to the end of a docstring after an escaped quote (#17216)
  • `airflow`

Bug fixes

  • Raise syntax error when \ is at end of file (#17409)

0.11.5

Preview features

  • `airflow`
  • `airflow`
  • `airflow`
  • `airflow`
  • [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`

Rule changes

  • `ruff`
  • `flake8-pytest-style`

Documentation

  • Fix formatting of "See Style Guide" link (#17272)

0.11.4

Preview features

  • `ruff`
  • [syntax-errors] Detect duplicate keys in match mapping patterns (#17129)
  • [syntax-errors] Detect duplicate attributes in match class patterns (#17186)
  • [syntax-errors] Detect invalid syntax in annotations (#17101)

Bug fixes

  • [syntax-errors] Fix multiple assignment error for class fields in match patterns (#17184)
  • Don't skip visiting non-tuple slice in typing.Annotated subscripts (#17201)

0.11.3

Preview features

  • `airflow`
  • `airflow`
  • `airflow`
  • `flake8-bandit`
  • `ruff`
  • [syntax-errors] Start detecting compile-time syntax errors (#16106)
  • [syntax-errors] Duplicate type parameter names (#16858)
  • [syntax-errors] Irrefutable case pattern before final case (#16905)
  • [syntax-errors] Multiple assignments in case pattern (#16957)
  • [syntax-errors] Single starred assignment target (#17024)
  • [syntax-errors] Starred expressions in return, yield, and for (#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.toml correctly when it is passed via stdin (#16971)

Configuration

  • `flake8-import-conventions`

Documentation

  • `refurb`

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`
  • [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 FixAll action in presence of version-specific syntax errors (#16848)
  • `flake8-bandit`
  • `refurb`
  • `refurb`
  • Fix --statistics reporting for unsafe fixes (#16756)

Rule changes

  • `flake8-executables`

CLI

  • Add --exit-non-zero-on-format (#16009)

Documentation

  • Update Ruff tutorial to avoid non-existent fix in __init__.py (#16818)
  • `flake8-gettext`

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-version is not specified (#16319)

    In previous versions of Ruff, you could specify your Python version with:

    • The target-version option in a ruff.toml file or the [tool.ruff] section of a pyproject.toml file.
    • The project.requires-python field in a pyproject.toml file 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.toml files without a [tool.ruff] section would be ignored, including the requires-python setting. 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.toml file without a target-version, it will check for a pyproject.toml file in the same directory and respect its requires-python version, even if it does not contain a [tool.ruff] section.
    • If Ruff finds a user-level configuration, the requires-python field of the closest pyproject.toml in a parent directory will take precedence.
    • If there is no config file (ruff.tomlor pyproject.toml with a [tool.ruff] section) in the directory of the file being checked, Ruff will search for the closest pyproject.toml in the parent directories and use its requires-python setting.

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 for statement 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-version is not specified (#16319)

    Because of a mistake in the release process, the requires-python inference 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_CHECKING behavior (#16669)

    Previously, Ruff only recognized typechecking blocks that tested the typing.TYPE_CHECKING symbol. Now, Ruff recognizes any local variable named TYPE_CHECKING. This release also removes support for the legacy if 0: and if False: typechecking checks. Use a local TYPE_CHECKING variable 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:

Remapped rules

The following rules have been remapped to new rule codes:

  • `unsafe-markup-use`

Stabilization

The following rules have been stabilized and are no longer in preview:

The following behaviors have been stabilized:

The following fixes or improvements to fixes have been stabilized:

Server

  • Remove logging output for ruff.printDebugInformation (#16617)

Configuration

  • `flake8-builtins`

Bug fixes

  • [flake8-bandit] Fix mixed-case hash algorithm names (S324) (#16552)

CLI

  • [ruff] Fix last_tag/commits_since_last_tag for version command (#16686)

0.9.10

Preview features

  • `ruff`
  • `syntax-errors`
  • `syntax-errors`
  • `syntax-errors`
  • `syntax-errors`
  • `syntax-errors`
  • `syntax-errors`
  • `syntax-errors`
  • `syntax-errors`
  • `syntax-errors`

Bug fixes

  • Escape template filenames in glob patterns in configuration (#16407)
  • `flake8-simplify`
  • Formatter: Fix syntax error location in notebooks (#16499)
  • `pyupgrade`
  • `flake8-builtins`
  • `pylint`

CLI

  • Move rule code from description to check_name in GitLab output serializer (#16437)

Documentation

  • `pydocstyle`

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`
  • `pylint`
  • `ruff`

Server

  • Avoid indexing the project if configurationPreference is editorOnly (#16381)
  • Avoid unnecessary info at non-trace server log level (#16389)
  • Expand ruff.configuration to allow inline config (#16296)
  • Notify users for invalid client settings (#16361)

Configuration

  • Add per-file-target-version option (#16257)

Bug fixes

  • `refurb`
  • `flake8-self`
  • `pylint`
  • `flake8-pyi`

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`
  • `refurb`
  • `ruff`
  • `ruff`
  • `refurb`

Rule changes

  • `flake8-debugger`
  • `pycodestyle`

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.ruff and source.fixAll.ruff code 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 noqa even when there are no diagnostics (#16178)
  • Better error messages while loading configuration extends (#15658)

Bug fixes

  • `flake8-comprehensions`
  • `flake8-pyi`
  • `pydocstyle`
  • `pylint`
  • `pylint`
  • `pyupgrade`
  • `pyupgrade`
  • `pyupgrade`
  • `refurb`
  • `ruff`

Documentation

  • Add FAQ entry for source.* code actions in Notebook (#16212)
  • Add SECURITY.md (#16224)

0.9.6

Preview features

  • `airflow`
  • `flake8-builtins`
  • `flake8-pyi`
  • `pylint`
  • `ruff`
  • `ruff`

Rule changes

  • `flake8-annotations`
  • `flake8-builtins`
  • `flake8-comprehensions`
  • `flake8-pie`
  • `flake8-simplify`
  • `pylint`
  • `pyupgrade`
  • `pyupgrade`
  • `pyupgrade`
  • `pyupgrade`
  • `ruff`

Server

  • Root exclusions in the server to project root (#16043)

Bug fixes

  • `flake8-datetime`
  • `flake8-type-checking`

Documentation

  • Improve ruff-lsp migration document (#16072)
  • Undeprecate ruff.nativeServer (#16039)

0.9.5

Preview features

  • Recognize all symbols named TYPE_CHECKING for in_type_checking_block (#15719)
  • `flake8-comprehensions`
  • `flake8-logging`
  • `flake8-pyi`
  • `flake8-pyi`
  • `flake8-pyi`
  • `flake8-pyi`
  • `pylint`
  • `pyupgrade`
  • `pyupgrade`
  • `refurb`
  • `refurb`
  • `ruff`
  • `airflow`
  • `flake8-pyi`
  • `flake8-pyi`

Rule changes

  • Preserve triple quotes and prefixes for strings (#15818)
  • `flake8-comprehensions`
  • `flake8-pyi`
  • `pep8-naming`
  • `pyupgrade`
  • `ruff`
  • `pycodestyle`

Configuration

  • Config error only when flake8-import-conventions alias conflicts with isort.required-imports bound name (#15918)
  • Workaround Even Better TOML crash related to allOf (#15992)

Bug fixes

  • `flake8-comprehensions`
  • `flake8-comprehensions`
  • `flake8-pyi`
  • `pep8-naming`
  • `pyflakes`
  • `pylint`
  • `refurb`
  • `refurb`

Documentation

  • Add deprecation warning for ruff-lsp related 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.extendIgnore editor setting (#15844)
  • Update black deviations (#15928)
  • Mention UP049 in UP046 and UP047, add See also section to UP040 (#15956)
  • Add instance variable examples to RUF012 (#15982)
  • Explain precedence for ignore and select config (#15883)

0.9.4

Preview features

  • `airflow`
  • `airflow`
  • `flake8-bandit`
  • `pylint`
  • `refurb`
  • `ruff`
  • `ruff`
  • `ruff`
  • `ruff`

Rule changes

  • Preserve quote style in generated code (#15726, #15778, #15794)
  • `flake8-bugbear`
  • `pylint`
  • `pyupgrade`

CLI

  • Fix formatter warning message for flake8-quotes option (#15788)
  • Implement tab autocomplete for ruff config (#15603)

Bug fixes

  • `flake8-comprehensions`
  • `flake8-comprehensions`
  • `pyupgrade`

Documentation

  • Add missing config docstrings (#15803)
  • Add references to trio.run_process and anyio.run_process (#15761)
  • Use uv init --lib in tutorial (#15718)

0.9.3

Preview features

  • `airflow`
  • `airflow`
  • `flake8-bandit`
  • `flake8-pytest-style`
  • `flake8-simplify`
  • `pyflakes`
  • `pylint`
  • `pylint`
  • `pyupgrade`
  • `refurb`
  • `ruff`
  • `ruff`

Rule changes

  • `flake8-bugbear`
  • `flake8-comprehensions`
  • `flake8-pytest-style`
  • `flake8-simplify`
  • `flake8-type-checking`
  • `isort`
  • `pydoclint`
  • `pyflakes`
  • `pyflakes`
  • `pyflakes`
  • `pylint`
  • `ruff`

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-fixes settings for code actions (#15666)

Bug fixes

  • `flake8-bandit`
  • `flake8-import-conventions`
  • `flake8-simplify`
  • `pyflakes`
  • `pyupgrade`
  • `ruff`
  • 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`
  • `airflow`
  • `fastapi`
  • `flake8-pytest-style`
  • `flake8-pytest-style`
  • `flake8-type-checking`

Rule changes

  • `flake8-todos`
  • `pyflakes`

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.configuration errors (#15452)

Configuration

  • Remove flatten to improve deserialization error messages (#15414)

Bug fixes

  • Parse triple-quoted string annotations as if parenthesized (#15387)
  • `fastapi`
  • `flake8-bandit`
  • `flake8-pathlib`
  • `ruff`

0.9.1

Preview features

  • `pycodestyle`
  • `ruff`

Rule changes

  • `flake8-bugbear`

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`
  • `pyupgrade`

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 doesnt remove or remap any existing stable rules.

Stabilization

The following rules have been stabilized and are no longer in preview:

The following behaviors have been stabilized:

The following fixes or improvements to fixes have been stabilized:

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 ISC001 incompatibility warning (#15123)
  • Prefer parenthesizing the assert message over breaking the assertion expression (#9457)
  • Automatically parenthesize over-long if guards in match case clauses (#13513)
  • More consistent formatting for match case patterns (#6933)
  • Avoid unnecessary parentheses around return type annotations (#13381)
  • Keep the opening parentheses on the same line as the if keyword for comprehensions where the condition has a leading comment (#12282)
  • More consistent formatting for with statements 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`
  • `flake8-type-checking`
  • `pylint`
  • `pyupgrade`
  • `ruff`
  • `ruff`

Rule changes

  • `flake8-builtins`
  • `flake8-return`

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 logLevel server setting which defaults to info. This addresses the issue where users were notified about an error and told to consult the log, but it didnt contain any messages. (#15232)
  • Ignore diagnostics from other sources for code action requests (#15373)

CLI

  • Improve the error message for --config key=value when the key is for a table and its a simple value

Bug fixes

  • `eradicate`
  • `flake8-django`
  • `pycodestyle`
  • `pydocstyle`
  • `pyflakes`
  • `refurb`
  • `ruff`
  • `ruff`

0.8.6

Preview features

  • `format`
  • `ruff`
  • `ruff`

Rule changes

  • `flake8-todos`
  • `pyflakes`

CLI

  • Show errors for attempted fixes only when passed --verbose (#15237)

Bug fixes

  • `ruff`
  • `pyupgrade`

0.8.5

Preview features

  • `airflow`
  • `airflow`
  • `fastapi`
  • `flake8-type-checking`
  • `pylint`
  • `ruff`
  • `ruff`
  • `ruff`

Rule changes

  • Visit PEP 764 inline TypedDict keys as non-type-expressions (#15073)
  • `flake8-comprehensions`
  • `flake8-pie`
  • `flake8-simplify`
  • `flake8-use-pathlib`
  • `pycodestyle`
  • `pydocstyle`
  • `pyupgrade`

Configuration

  • `flake8-type-checking`
  • `pydocstyle`
  • `ruff`

Bug fixes

  • Fix type subscript on older python versions (#15090)
  • Use TypeChecker for detecting fastapi routes (#15093)
  • `pycodestyle`

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`
  • `airflow`
  • `flake8-use-pathlib`
  • `perflint`
  • `perflint`
  • `pylint`
  • `ruff`
  • `ruff`

Rule changes

  • `flake8-bandit`
  • `flake8-pyi`
  • `pydocstyle`
  • `ruff`

Bug

  • `perflint`

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`
  • `airflow`
  • `flake8-bugbear`
  • `flake8-bugbear`
  • `flake8-use-pathlib`
  • `pylint`
  • `ruff`
  • `ruff`
  • `ruff`
  • `ruff`
  • `ruff`

Rule changes

  • `flake8-bugbear`
  • `flake8-pyi`
  • `pyupgrade`
  • `pyupgrade`

Bug fixes

  • Raise syntax error for mixing except and except* (#14895)
  • `flake8-bugbear`
  • `flake8-bugbear`
  • `flake8-comprehensions`
  • `flake8-pyi`
  • `flake8-pytest-style`
  • `perflint`
  • `pylint`

0.8.2

Preview features

  • `airflow`
  • `airflow`
  • `ruff`
  • `ruff`
  • `ruff`

Rule changes

  • `airflow`
  • `flake8-pytest-style`
  • `pandas-vet`
  • `pylint`
  • `refurb`

Configuration

  • `flake8-import-conventions`

Bug fixes

  • Revert: [pyflakes] Avoid false positives in @no_type_check contexts (F821, F722) (#14615) (#14726)
  • `pep8-naming`
  • `pycodestyle`
  • `pylint`
  • `refurb`
  • `ruff`

Documentation

  • Improve docs for flake8-use-pathlib rules (#14741)
  • Improve error messages and docs for flake8-comprehensions rules (#14729)
  • `flake8-type-checking`

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`
  • `flake8-builtins`
  • `flake8-pytest-style`
  • `flake8-type-checking`
  • `flake8-type-checking`
  • `flake8-use-pathlib`
  • `pylint`
  • `pylint`
  • `refurb`
  • `ruff`
  • `ruff`
  • `ruff`
  • `ruff`

Rule changes

  • Ignore more rules for stub files (#14541)
  • `pep8-naming`
  • `pyflakes`
  • `ruff`
  • `ruff`

Bug fixes

  • Avoid fixing code to None | None for redundant-none-literal (PYI061) and never-union (RUF020) (#14583, #14589)
  • `flake8-bugbear`
  • `flake8-pyi`, `ruff`
  • `flake8-pyi`
  • `flake8-type-checking`
  • `pylint`
  • `ruff`

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-version or project.requires-python (#13896)

  • Changed location of pydoclint diagnostics

    pydoclint diagnostics 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 noqa comments in some places, this change may mean that you need to move the noqa suppression comments. Most users should be unaffected by this change.

  • Use XDG (i.e. ~/.local/bin) instead of the Cargo home directory in the standalone installer

    Previously, Ruff's installer used $CARGO_HOME or ~/.cargo/bin for 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:

Remapped rules

The following rules have been remapped to new rule codes:

Stabilization

The following rules have been stabilized and are no longer in preview:

The following behaviors have been stabilized:

The following fixes have been stabilized:

Preview features

  • `flake8-datetimez`
  • `flake8-pie`
  • `flake8-pyi`
  • `flake8-pyi`
  • `ruff`
  • `ruff`
  • `ruff`
  • `pycodestyle`
  • `pylint`

Rule changes

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.aliases only uses valid module names and aliases (#14477)

0.7.4

Preview features

  • `flake8-datetimez`
  • `flake8-logging`
  • `flake8-no-pep420`
  • `flake8-pyi`
  • `perflint`
  • `pylint`
  • `ruff`
  • `ruff`
  • `ruff`

Rule changes

  • `flake8-boolean-trap`
  • `flake8-pyi`
  • `flake8-pyi`
  • `flake8-pyi`
  • `flake8-pyi`

Server

  • Use the current working directory to resolve settings from ruff.configuration (#14352)

Bug fixes

  • Avoid conflicts between PLC014 (useless-import-alias) and I002 (missing-required-import) by considering lint.isort.required-imports for PLC014 (#14287)
  • `flake8-type-checking`
  • `flake8-pyi`
  • `flake8-pytest-style`
  • `flake8-simplify`
  • `flake8-type-checking`
  • `pylint`
  • `pylint`
  • `pyupgrade`
  • `pyupgrade`
  • `refurb`
  • `refurb`
  • `refurb`
  • `ruff`
  • `ruff`

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`
  • `flake8-simplify`
  • `refurb`
  • `ruff`

Rule changes

  • Detect items that hash to same value in duplicate sets (B033, PLC0208) (#14064)
  • `eradicate`
  • `flake8-pyi`
  • `flake8-pyi`
  • `pyflakes`
  • `ruff`

Bug fixes

  • Avoid parsing joint rule codes as distinct codes in # noqa (#12809)
  • `eradicate`
  • `flake8-bugbear`
  • `flake8-builtins`
  • `flake8-comprehension`
  • `flake8-simplify`
  • `pylint`
  • `pylint`
  • `pyupgrade`
  • `refurb`

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`

Rule changes

  • Regenerate known_stdlibs.rs with stdlibs 2024.10.25 (#13963)
  • `flake8-no-pep420`

Server

  • Fix server panic when undoing an edit (#14010)

Bug fixes

  • Fix issues in discovering ruff in pip build environments (#13881)
  • `flake8-type-checking`
  • `flake8-type-checking`

Documentation

  • `flake8-simplify`

0.7.1

Preview features

  • Fix E221 and E222 to 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`

Rule changes

  • `flake8-type-checking`

Server

  • Avoid indexing the workspace for single-file mode (#13770)

Bug fixes

  • Make ARG002 compatible with EM101 when raising NotImplementedError (#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 PT001 and PT023 now 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-except rule (in our tryceratops category) has been recoded from TRY302 to TRY203 (#13502). This ensures Ruff's code is consistent with the same rule in the tryceratops linter.
  • The lint.allow-unused-imports setting has been removed (#13677). Use lint.pyflakes.allow-unused-imports instead.

Formatter preview style

  • Normalize implicit concatenated f-string quotes per part (#13539)

Preview linter features

  • `refurb`
  • `refurb`

Rule changes

  • `pylint`
  • `flake8-async`
  • `flake8-bugbear`
  • `flake8-todos`
  • `pycodestyle`
  • `flake8-simplify`
    being opened from a wider range of standard-library functions (#12959).

CLI

  • Add explanation of fixable in --statistics command (#13774)

Bug fixes

  • `pyflakes`
  • `flake8-use-pathlib`
  • `flake8-bandit`
  • `flake8-pyi`

0.6.9

Preview features

  • Fix codeblock dynamic line length calculation for indented docstring examples (#13523)
  • `refurb`

Rule changes

  • `pydocstyle`
  • `pylint`

Configuration

  • `pyflakes`

Bug fixes

  • Support ruff discovery in pip build environments (#13591)
  • `flake8-bugbear`
  • `pylint`
  • `pyupgrade`
  • `refurb`

Documentation

  • Update GitHub Action link to astral-sh/ruff-action (#13551)

0.6.8

Preview features

  • Remove unnecessary parentheses around match case clauses (#13510)
  • Parenthesize overlong if guards in match..case clauses (#13513)
  • Detect basic wildcard imports in ruff analyze graph (#13486)
  • `pylint`

Rule changes

  • `lake8-simplify`
  • `pyupgrade`

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

  • Reuse BTreeSets in module resolver (#13440)
  • Skip traversal for non-compound statements (#13441)

0.6.7

Preview features

  • Add Python version support to ruff analyze CLI (#13426)
  • Add exclude support to ruff analyze (#13425)
  • Fix parentheses around return type annotations (#13381)

Rule changes

  • `pycodestyle`

Bug fixes

  • Respect lint.exclude in ruff check --add-noqa (#13427)

Performance

  • Avoid tracking module resolver files in Salsa (#13437)
  • Use forget for module resolver database (#13438)

0.6.6

Preview features

  • `refurb`
  • 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::offset calculation (#13407)

Bug fixes

  • `fastapi`
  • `pydocstyle`

Documentation

  • Add backlinks to rule overview linter (#13368)
  • Fix documentation for editor vim plugin ALE (#13348)
  • Fix rendering of FURB188 docs (#13406)

0.6.5

Preview features

  • `pydoclint`
  • `refurb`

Rule changes

  • `eradicate`
  • `pyflakes`

Server

  • Add support for extensionless Python files for server (#13326)
  • Fix configuration inheritance for configurations specified in the LSP settings (#13285)

Bug fixes

  • `ruff`

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`
  • `pydoclint`
  • `pylint`
  • `ruff`
  • `ruff`

Rule changes

  • `flake8-pyi`
  • `flake8-pyi`
  • `pylint`
  • `pylint`
  • `pyupgrade`
  • `pyupgrade`

CLI

  • Enrich messages of SARIF results (#13180)
  • Handle singular case for incompatible rules warning in ruff format output (#13212)

Bug fixes

  • `pydocstyle`
  • `refurb`

0.6.3

Preview features

  • `flake8-simplify`
  • `pycodestyle`
  • `pydoclint`

Rule changes

  • `flake8-async`

Bug fixes

  • `FastAPI`
  • `flake8-implicit-str-concat`
  • `flake8-pytest-style`
  • `pylint`
  • `ruff`
  • `ruff`
  • Fix dark theme on initial page load for the Ruff playground (#13077)

0.6.2

Preview features

  • `flake8-simplify`
  • `ruff`
  • `ruff`
  • `ruff`

Rule changes

  • `flake8-bugbear`
  • `flake8-pyi`
  • `flake8-type-checking`
  • `flake8-unused-arguments`
  • `pylint`

Server

  • Show full context in error log messages (#13029)

Bug fixes

  • `pep8-naming`
  • `pylint`

Documentation

  • Add hyperfine installation instructions; update hyperfine code samples (#13034)
  • Expand note to use Ruff with other language server in Kate (#12806)
  • Update example for PT001 as per the new default behavior (#13019)
  • `perflint`
  • `pydocstyle`

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`

Rule changes

  • `pylint`

Server

  • Fix crash when applying "fix-all" code-action to notebook cells (#12929)

Other changes

  • `flake8-naming`

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 src layouts by default for isort rules (#12848)
  • The pytest rules PT001 and PT023 now default to omitting the decorator parentheses when there are no arguments (#12838).

Deprecations

The following rules are now deprecated:

Remapped rules

The following rules have been remapped to new rule codes:

Stabilization

The following rules have been stabilized and are no longer in preview:

The following behaviors have been stabilized:

The following fixes have been stabilized:

Preview features

  • `flake8-simplify`
  • `pyupgrade`

Rule changes

  • `flake8-import-conventions`
  • `flake8-pytest-style`

Server

  • Show a message for incorrect settings (#12781)

Bug fixes

  • `flake8-async`
  • `flake8-comprehensions`
  • `flake8-return`
  • `flake8-type-checking`
  • `pep8-naming`
  • `pydoclint`
  • `ruff`
  • `ruff`
  • `ruff`
  • `ruff`
  • 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 kernelspec notebook metadata when detecting the preferred language for a Jupyter Notebook (#12875)

0.5.7

Preview features

  • `flake8-comprehensions`
  • `flake8-pyi`
  • `flake8-return`
  • `pydoclint`
  • `pydoclint`
  • `pydoclint`
  • `pydoclint`
  • `pydoclint`
  • `ruff`
  • `ruff`

Rule changes

  • `refurb`
  • `ruff`
  • `tryceratops`

Server

  • Ignore non-file workspace URL; Ruff will display a warning notification in this case (#12725)

CLI

  • Fix cache invalidation for nested pyproject.toml files (#12727)

Bug fixes

  • `flake8-async`
  • `flake8-bandit`
  • `flake8-bugbear`
  • `flake8-comprehensions`
  • `flake8-simplify`
  • `pydoclint`

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`
  • `pydoclint`

Rule changes

  • `flake8-return`

Server

  • Make server panic hook more error resilient (#12610)
  • Use $/logTrace for server trace logs in Zed and VS Code (#12564)
  • Keep track of deleted cells for reorder change request (#12575)

Configuration

  • `flake8-implicit-str-concat`

Bug fixes

  • `flake8-async`
  • `flake8-slots`
  • `isort`
  • `isort`
  • `pycodestyle`
  • `pycodestyle`
  • `pyflakes`
  • `pylint`
  • `pyupgrade`
  • `pyupgrade`
  • 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`
  • `pydoclint`

Rule changes

  • `numpy`
  • `numpy`
  • `pep8-naming`

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 Ord implementation of cmp_fix (#12471)
  • Raise syntax error for unparenthesized generator expression in multi-argument call (#12445)
  • `pydoclint`
  • `flake8-bugbear`

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`

Bug fixes

  • `flake8-builtins`
  • `flake8-comprehensions`
  • `pydocstyle`

Documentation

  • Fix GitHub link to Neovim setup (#12410)
  • Fix output-format default in settings reference (#12409)

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`

Rule changes

  • `flake8-bugbear`
  • `flake8-bugbear`
  • `pylint`
  • `pylint`
  • `pylint`

Server

  • Build settings index in parallel for the native server (#12299)
  • Use fallback settings when indexing the project (#12362)
  • Consider --preview flag for server subcommand for the linter and formatter (#12208)

Bug fixes

  • `flake8-comprehensions`
  • `pylint`
  • `pylint`

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 space separator before parenthesized expressions in comprehensions with leading comments (#12282)
  • `flake8-async`
  • `flake8-async`
  • `flake8-async`
  • `flake8-async`
  • `flake8-async`

Rule changes

  • `flake8-return`
  • `numpy`
  • `refurb`

Server

  • Consider include and extend-include settings 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 not operations as boolean tests (#12301)
  • `flake8-bandit`
  • `flake8-bandit`
  • `flake8-bandit`
  • `pycodestyle`
  • `pyflakes`
  • `refurb`

Documentation

  • Update help and documentation to reflect --output-format full default (#12248)

Performance

  • Use more threads when discovering Python files (#12258)

0.5.1

Preview features

  • `flake8-bugbear`
  • `pycodestyle`
  • `pytest`

Rule changes

  • Enable token-based rules on source with syntax errors (#11950)
  • `flake8-bandit`
  • `numpy`
  • `pylint`

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-python inference robust to == (#12091)
  • Use char-wise width instead of str-width (#12135)
  • `pycodestyle`
  • `pycodestyle`
  • `pylint`

Performance

  • Remove allocation in parse_identifier (#12103)
  • Use CompactString for Identifier AST node (#12101)

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 ALL now excludes deprecated rules
  • The released archives now include an extra level of nesting, which can be removed with --strip-components=1 when untarring.
  • The release artifact's file name no longer includes the version tag. This enables users to install via /latest URLs on GitHub.
  • The diagnostic ranges for some flake8-bandit rules were modified (#10667).

Deprecations

The following rules are now deprecated:

Remapped rules

The following rules have been remapped to new rule codes:

Stabilization

The following rules have been stabilized and are no longer in preview:

The following behaviors have been stabilized:

Removals

The following deprecated settings have been removed:

  • output-format=text; use output-format=concise or output-format=full
  • tab-size; use indent-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>; use ruff check <path>
  • ruff --clean; use ruff clean
  • ruff --generate-shell-completion; use ruff generate-shell-completion

Preview features

  • `ruff`

CLI

  • Use rule name rather than message in --statistics (#11697)
  • Use the output format full by default (#12010)
  • Don't log syntax errors to the console (#11902)

Rule changes

  • `ruff`
  • `numpy`
  • `flake8-bandit`

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`
  • `pep8-naming`
  • `pyflakes`

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`
  • `pycodestyle`

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`
  • `refurb`

Rule changes

  • `pycodestyle`

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.printDebugInformation command (#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`
  • `flake8-bugbear`
  • `refurb`

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`
  • `flake8-pyi`
  • `pygrep_hooks`

Rule changes

  • `pyupgrade`
  • `numpy`

Server

  • Formatting a document with syntax problems no longer spams a visible error popup (#11745)

CLI

  • Add RDJson support for --output-format flag (#11682)

Bug fixes

  • `pyupgrade`
  • `flake8-simplify`
  • Ensure the expression generator adds a newline before type statements (#11720)
  • Respect per-file ignores for blanket and redirected noqa rules (#11728)

0.4.7

Preview features

  • `flake8-pyi`
  • `flake8-pyi`
  • `flake8-pyi`
  • `pyflakes`

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`
  • Mark repeated-isinstance-calls as 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`

Rule changes

  • `numpy`
  • `mccabe`
  • Consider match-case statements for C901, PLR0912, and PLR0915 (#11521)
  • Remove empty strings when converting to f-string (UP032) (#11524)
  • `flake8-bandit`
  • `flake8-self`
  • `pyupgrade`

Server

  • Respect excludes in ruff server configuration discovery (#11551)
  • Use default settings if initialization options is empty or not provided (#11566)
  • ruff server correctly treats .pyi files as stub files (#11535)
  • ruff server searches 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`
  • `refurb`
  • `flake8-simplify`
  • Create intermediary directories for --output-file (#11550)
  • Propagate reads on global variables (#11584)
  • Treat all singledispatch arguments 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`
  • `isort`
  • `pycodestyle`
  • `pyflakes`
  • `pyflakes`
  • `pyupgrade`

Formatter

  • Avoid multiline quotes warning with quote-style = preserve (#11490)

Server

  • Support Jupyter Notebook files (#11206)
  • Support noqa comment code actions (#11276)
  • Fix automatic configuration reloading (#11492)
  • Fix several issues with configuration in Neovim and Helix (#11497)

CLI

  • Add --output-format as a CLI option for ruff config (#11438)

Bug fixes

  • Avoid PLE0237 for property with setter (#11377)
  • Avoid TCH005 for if stmt with elif/else block (#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`
  • `pylint`
  • `pylint`
  • `refurb`

Documentation

  • Add --preview to 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`
  • `pyflakes`
  • `pylint`

0.4.4

Preview features

  • `pycodestyle`
  • `pylint`
  • `flake8-pyi`
  • `flake8-pyi`

Rule changes

  • `flake8-boolean-trap`
  • `flake8-bugbear`

Server

  • Expand tildes when resolving Ruff server configuration file (#11283)
  • Fix ruff server hanging after Neovim closes (#11291)
  • Editor settings are used by default if no file-based configuration exists (#11266)

Bug fixes

  • `pylint`
  • `flake8-blind-except`, `tryceratops`
  • 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`
  • `refurb`
  • `refurb`
  • `ruff`
  • `pyflakes`

Rule changes

  • `flake8-bugbear`
  • `flake8-logging`
  • `pylint`
  • `ruff`

Formatter

  • Avoid multiline expression if format specifier is present (#11123)

LSP

  • Write ruff server setup guide for Helix (#11183)
  • ruff server no longer hangs after shutdown (#11222)
  • ruff server reads from a configuration TOML file in the user configuration directory if no local configuration exists (#11225)
  • ruff server respects per-file-ignores configuration (#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`
  • `ruff`
  • `pygrep_hooks`
  • `perflint`
  • `pyflakes`

Performance

  • Avoid allocations for isort module names (#11251)
  • Build a separate ARM wheel for macOS (#11149)

Windows

  • Increase the minimum requirement to Windows 10.

0.4.2

Rule changes

  • `flake8-pyi`
  • `pyupgrade`
  • `refurb`

Server

  • Fix an issue with missing diagnostics for Neovim and Helix (#11092)
  • Implement hover documentation for noqa codes (#11096)
  • Introduce common Ruff configuration options with new server settings (#11062)

Bug fixes

  • Use macos-12 for building release wheels to enable macOS 11 compatibility (#11146)
  • `flake8-blind-expect`
  • `flake8-pyi`
  • `flake8-simplify`
  • `refurb`
  • `ruff`
  • `ruff`

Documentation

  • `flake8-bugbear`
  • `flake8-type-checking`
  • `isort`
  • `pylint`

Performance

  • Use matchit to resolve per-file settings (#11111)

0.4.1

Preview features

  • `pylint`
  • `pylint`

Bug fixes

  • `pylint`
  • Parser: Use empty range when there's "gap" in token source (#11032)
  • `ruff`
  • 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. Its 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, and ruff.applyOrganizeImports
  • Supports source.fixAll and source.organizeImports source 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`
  • `pylint`
  • `pylint`
  • `pylint`
  • `pylint`
  • `ruff`

Rule changes

  • `flake8-bandit`
  • `flake8-bugbear`
  • `flake8-slots`
  • `pylint`

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_FILE environment variable support (#10992)

Bug fixes

  • Avoid non-augmented-assignment for reversed, non-commutative operators (PLR6104) (#10909)
  • Limit commutative non-augmented-assignments to primitive data types (PLR6104) (#10912)
  • Respect per-file-ignores for RUF100 on blanket # noqa (#10908)
  • Consider if expression for parenthesized with items parsing (#11010)
  • Consider binary expr for parenthesized with items parsing (#11012)
  • Reset FOR_TARGET context for all kinds of parentheses (#11009)

0.3.7

Preview features

  • `flake8-bugbear`
  • `pylint`

Bug fixes

  • Avoid TOCTOU errors in cache initialization (#10884)
  • `pylint`
  • `pylint`

0.3.6

Preview features

  • `pylint`
  • `pylint`
  • `pyupgrade`
  • `refurb`
  • `refurb`
  • `refurb`
  • `refurb`
  • `flake8_comprehensions`

Rule changes

  • `pydocstyle`
  • `pycodestyle`
  • `flake8-pyi`
  • `flake8-slots`
  • `pyflakes`
  • `pygrep-hooks`

CLI

  • Support FORCE_COLOR env var (#10839)

Configuration

  • Support negated patterns in [extend-]per-file-ignores (#10852)

Bug fixes

  • `flake8-import-conventions`
  • `flake8-quotes`
  • `pep8-naming`
  • `flake8-quotes`
  • `flake8-simplify`
  • `ruff`
  • `flake8-pytest-style`
  • `flake8-return`
  • `refurb`
  • `pylint`
  • `pydocstyle`
  • Respect # noqa directives on __all__ openers (#10798)

0.3.5

Preview features

  • `pylint`
  • `refurb`
  • `refurb`
  • `refurb`

Rule changes

  • `flake8-comprehensions`
  • `flake8-pyi`
  • `numpy`
  • `pycodestyle`
  • `pycodestyle`

Configuration

  • Respected nested namespace packages (#10541)
  • `flake8-boolean-trap`

Bug fixes

  • Correctly handle references in __all__ definitions when renaming symbols in autofixes (#10527)
  • Track ranges of names inside __all__ definitions (#10525)
  • `flake8-bugbear`
  • `flake8-copyright`
  • `flake8-datetimez`
  • `flake8-pytest-style`
  • `flake8-quotes`
  • `isort`
  • `isort`
  • `pyflakes`
  • `pyflakes`
  • `pylint`
  • `ruff`

Documentation

  • Add PR title format to CONTRIBUTING.md (#10665)
  • Fix list markup to include blank lines required (#10591)
  • Put flake8-logging next to the other flake8 plugins in registry (#10587)
  • `flake8-bandit`
  • `flake8-bugbear`
  • `flake8-datetimez`
  • `pycodestyle`
  • `ruff`

0.3.4

Preview features

  • `flake8-simplify`
  • `pylint`
  • `pylint`
  • `pylint`
  • `refurb`

Rule changes

  • `flake8-pytest-style`
  • `pycodestyle`

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 name from 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 .pyi files (#10512)
  • Fix E231 bug: Inconsistent catch compared to pycodestyle, such as when dict nested in list (#10469)
  • Fix pylint upstream categories not showing in docs (#10441)
  • Add missing Options references to blank line docs (#10498)
  • 'Revert "F821: Fix false negatives in .py files when from __future__ import annotations is active (#10362)"' (#10513)
  • Apply NFKC normalization to unicode identifiers in the lexer (#10412)
  • Avoid failures due to non-deterministic binding ordering (#10478)
  • `flake8-bugbear`
  • `flake8-quotes`

0.3.3

Preview features

  • `flake8-bandit`
  • `pycodestyle`
  • `pycodestyle`
  • `pylint`

Rule changes

  • `flake8_comprehensions`
  • `flake8-bandit`
  • `pyflakes`
  • `pylint`
  • `pylint`

CLI

  • Add message on success to ruff check (#8631)

Bug fixes

  • `PIE970`
  • Avoid TRIO115 if the argument is a variable (#10376)
  • `F811`
  • Fix F821 and F822 false positives in .pyi files (#10341)
  • Fix F821 false negatives in .py files when from __future__ import annotations is active (#10362)
  • Fix case where Indexer fails to identify continuation preceded by newline #10351 (#10354)
  • Sort hash maps in Settings display (#10370)
  • Track conditional deletions in the semantic model (#10415)
  • `C413`
  • `pycodestyle`
  • `pycodestyle`
  • `pylint`
  • Gate f-string struct size test for Rustc < 1.76 (#10371)

Documentation

  • Use ruff.toml format in README (#10393)
  • `RUF008`
  • `pylint`
  • Remove . from check and format commands (#10217)

0.3.2

Preview features

  • Improve single-with item formatting for Python 3.8 or older (#10276)

Rule changes

  • `pyupgrade`
  • `pycodestyle`

Bug fixes

  • Fix trailing kwargs end of line comment after slash (#10297)
  • Fix unstable with items formatting (#10274)
  • Avoid repeating function calls in f-string conversions (#10265)
  • Fix E203 false positive for slices in format strings (#10280)
  • Fix incorrect Parameter range for *args and **kwargs (#10283)
  • Treat typing.Annotated subscripts as type definitions (#10285)

0.3.1

Preview features

  • `pycodestyle`
  • `pycodestyle`
  • `pycodestyle`
  • `pylint`
  • `pylint`

Rule changes

  • `flake8-debugger`
  • `pyupgrade`
  • `pep8_naming`

CLI

  • Colorize the output of ruff format --diff (#10110)
  • Make --config and --isolated global 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-section setting (#10149)

Bug fixes

  • Remove trailing space from CapWords message (#10220)
  • Respect external codes in file-level exemptions (#10203)
  • `flake8-raise`
  • `pylint`
  • `ruff`

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`
  • `pycodestyle`
  • `pycodestyle`

Rule changes

  • `eradicate`
  • `eradicate`
  • `flake8-boolean-trap`
  • `flake8-copyright`
  • `isort`
  • `pylint`
  • `pylint`
  • `pyupgrade`
  • `ruff`

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 with parentheses 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 extend as part of a --config flag (#10135)
  • Remove build from the default exclusion list (#10093)
  • Deprecate ruff <path>, ruff --explain, ruff --clean, and ruff --generate-shell-completion in favor of ruff check <path>, ruff rule, ruff clean, and ruff generate-shell-completion (#10169)
  • Remove the deprecated CLI option --format from ruff rule and ruff linter (#10170)

Bug fixes

  • `flake8-bugbear`
  • `flake8-type-checking`
  • `pycodestyle`
  • `pydocstyle`
  • `pylint`
  • `ruff`
  • Fix ruff crashing 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-length option: fix link to pycodestyle.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 --config argument (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`
  • `refurb`

Rule changes

  • `ruff`
  • `numpy`
  • `flake8-bandit`
  • `ruff`
  • `flake8-pyi`

Formatter

  • Docstring formatting: Preserve tab indentation when using indent-style=tabs (#9915)
  • Disable top-level docstring formatting for notebooks (#9957)
  • Stabilize quote-style's preserve mode (#9922)

CLI

  • Allow arbitrary configuration options to be overridden via the CLI (#9599)

Bug fixes

  • Make show-settings filters 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`
  • `flake8-trio`
  • `perflint`
  • `pycodestyle`
  • `pydocstyle`
  • `pydocstyle`
  • `pylint`
  • `pylint`
  • `ruff`
  • `ruff`
  • `ruff`

Performance

  • Use memchr for string lexing (#9888)
  • Use memchr for tab-indentation detection (#9853)
  • Reduce Result<Tok, LexicalError> size by using Box<str> instead of String (#9885)
  • Reduce size of Expr from 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

  • `refurb`
  • Format module-level docstrings (#9725)

Formatter

  • Add --range option to ruff format (#9733)
  • Don't trim last empty line in docstrings (#9813)

Bug fixes

  • Skip empty lines when determining base indentation (#9795)
  • Drop __get__ and __set__ from unnecessary-dunder-call (#9791)
  • Respect generic Protocol in 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, and C418 (#9819)
  • Use AhoCorasick to speed up quote match (#9773)
  • Remove CST-based fixers for C405 and C409 (#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-args example to max-positional-args (#9797)
  • Fixed example code in weak_cryptographic_key.rs (#9774)
  • Fix references to deprecated ANN rules in changelog (#9771)
  • Fix default for max-positional-args (#9838)

0.2.0

Breaking changes

  • The NURSERY selector 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:

The following command line options are now deprecated:

  • --show-source; use --output-format full instead
  • --no-show-source; use --output-format concise instead
  • --output-format text; use full or concise instead

The following settings have moved and the previous name is deprecated:

Remapped rules

The following rules have been remapped to new codes:

Stabilizations

The following rules have been stabilized and are no longer in preview:

Fixes for the following rules have been stabilized and are now available without preview:

Fixes for the following rules have been promoted from unsafe to safe:

The following behaviors have been stabilized:

Preview features

  • `refurb`
  • Implement blank_line_after_nested_stub_class preview style (#9155)
  • The preview rule and-or-ternary (PLR1706) was removed

Bug fixes

  • `flake8-async`
  • `flake8-return`
  • 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`
  • `pylint`
  • Removing trailing whitespace inside multiline strings is unsafe (#9744)
  • Support IfExp with dual string arms in invalid-envvar-default (#9734)
  • `pylint`

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 NURSERY selector is used with --preview (#9682)
  • Preserve indentation around multiline strings in formatter (#9637)
  • `flake8-return`
  • `flake8-simplify`
  • `pycodestyle`
  • `pylint`
  • `pylint`
  • `pylint`
  • `pylint`
  • `pylint`
  • `ruff`
  • `ruff`
  • `ruff`
  • `ruff`

CLI

  • Enable auto-wrapping of --help output (#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`
  • `flake8-pie`
  • `flake8-return`
  • `flake8-return`
  • `flake8-return`
  • `flake8-simplify`
  • `flake8-type-checking`
  • `flake8-type-checking`
  • `pycodestyle`
  • `pydocstyle`

Documentation

  • `flake8-pytest-style`
  • `pylint`
  • `isort`

0.1.14

Preview features

  • `flake8-bugbear`
  • `flake8-simplify`
  • `pygrep_hooks`
  • `pylint`
  • `refurb`
  • `ruff`
  • `tryceratops`

Rule changes

  • `flake8-pyi`
  • `flake8-pyi`
  • `pylint`

CLI

  • --show-settings displays active settings in a far more readable format (#9464)
  • Add --extension support to the formatter (#9483)

Configuration

  • Ignore preview status for fixable and unfixable selectors (#9538)
  • `pycodestyle`

Bug fixes

  • Recursively visit deferred AST nodes (#9541)
  • Visit deferred lambdas before type definitions (#9540)
  • `flake8-simplify`
  • `pandas-vet`
  • `pylint`
  • `pylint`
  • `refurb`
  • `ruff`

Documentation

  • Add instructions on using noqa with 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`

0.1.13

Bug fixes

  • Include base pyproject when initializing cache settings (#9480)
  • `flake8-simplify`
  • `pylint`
  • `pylint`

0.1.12

Preview features

  • Formatter: Hug multiline-strings in preview style (#9243)
  • `flake8-bandit`
  • `flake8-bandit`
  • `flake8-bandit`
  • `flake8-bandit`
  • `flake8-simplify`
  • `pyflakes`
  • `pylint`
  • `ruff`

Rule changes

  • `flake8-boolean-trap`
  • `flake8-builtins`
  • `flake8-pyi`
  • `pyflakes`
  • `pyupgrade`
  • `ruff`
  • `ruff`
  • `ruff`

Formatter

  • Generate deterministic IDs when formatting notebooks (#9359)
  • Allow # fmt: skip with 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. None comparisons (#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 DisplayParseError for stdin parser errors (#9409)
  • Use comment_ranges for isort directive extraction (#9414)
  • Use transformed source code for diagnostic locations (#9408)
  • `flake8-pyi`
  • `flake8-pyi`
  • `pydocstyle`
  • `pylint`
  • `ruff`

Documentation

  • Fix admonition hyperlink colouring (#9385)
  • Add missing preview link (#9386)

0.1.11

Preview features

  • `pylint`

Bug fixes

  • Check path string properly in python -m ruff invocations (#9367)

Documentation

  • Tweak relative-imports message (#9365)
  • Add fix safety note for yield-in-for-loop (#9364)

0.1.10

Preview features

  • Improve dummy_implementations preview 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 with statements (#9222)
  • `flake8-pyi`
  • `pylint`
  • `refurb`
  • `ruff`

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-task for 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-noqa via per-file-ignores (#9300)
  • Respect attribute chains when resolving builtin call paths (#9309)
  • Treat all typing_extensions members as typing aliases (#9335)
  • Use Display for formatter parse errors (#9316)
  • Wrap subscripted dicts in parens for f-string conversion (#9238)
  • `flake8-annotations`
  • `flake8-annotations`
  • `flake8-bandit`
  • `pylint`
  • `pylint`
  • `refurb`

Documentation

  • Expand target name for better rule documentation (#9302)
  • Fix typos found by codespell (#9346)
  • `perflint`
  • `pyupgrade`

0.1.9

Breaking changes

  • Add site-packages to default exclusions (#9188)

Preview features

  • Fix: Avoid parenthesizing subscript targets and values (#9209)
  • `pylint`
  • Implement reimplemented_operator (FURB118) (#9171)
  • Add a rule to detect string members in runtime-evaluated unions (#9143)
  • Implement no_blank_line_before_class_docstring preview style (#9154)

Rule changes

  • CONSTANT_CASE variables are improperly flagged for yoda violation (SIM300) (#9164)
  • `flake8-pyi`
  • `flake8-bugbear`
  • Add fix to automatically remove print and pprint statements (T201, T203) (#9208)
  • Prefer Never to NoReturn in auto-typing in Python >= 3.11 (ANN201) (#9213)

Formatter

  • can_omit_optional_parentheses: Exit early for unparenthesized expressions (#9125)
  • Fix dynamic mode with doctests so that it doesn't exceed configured line width (#9129)
  • Fix can_omit_optional_parentheses for expressions with a right most fstring (#9124)
  • Add target_version to formatter options (#9220)

CLI

  • Update ruff format --check to 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 D208 with multibyte indent (#9147)
  • Add support for NoReturn in auto-return-typing (#9206)
  • Allow removal of typing from exempt-modules (#9214)
  • Avoid mutable-class-default violations for Pydantic subclasses (#9187)
  • Fix dropped union expressions for piped non-types in PYI055 autofix (#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-task violations 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_assignments preview style (#8943)
  • `pycodestyle`
  • `pycodestyle`
  • `pycodestyle`
  • `refurb`

Rule changes

  • Allow flake8-type-checking rules to automatically quote runtime-evaluated references (#6001)
  • Allow transparent cell magics in Jupyter Notebooks (#8911)
  • `flake8-annotations`
  • `flake8-self`
  • `pep8-naming`
  • `pycodestyle`
  • `pyflakes`
  • `pylint`

Formatter

  • Add docstring-code-format knob 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`
  • `flake8-pie`
  • `flake8-pie`
  • `flake8-raise`
  • `isort`
  • `isort`
  • `pycodestyle`
  • `pylint`
  • `pyupgrade`
  • `refurb`
  • `refurb`
  • `ruff`

0.1.7

Preview features

  • Implement multiline dictionary and list hugging for preview style (#8293)
  • Implement the fix_power_op_line_length preview style (#8947)
  • Use Python version to determine typing rewrite safety (#8919)
  • `flake8-annotations`
  • `flake8-bandit`
  • `flake8-bandit`
  • `flake8-pyi`
  • `flake8-simplify`
  • `pylint`
  • `pylint`
  • `pylint`
  • `pylint`
  • `pylint`
  • `refurb`

Rule changes

  • `flake8-boolean-trap`
  • `flake8-bugbear`
  • `flake8-pie`
  • `flake8-pyi`
  • `flake8-pyi`
  • `flake8-simplify`
  • `pep8-naming`
  • `pycodestyle`
  • `pycodestyle`
  • `pydocstyle`
  • `pylint`

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 check and ruff format to default to the current directory (#8791)
  • Stop at the first resolved parent configuration (#8864)

Configuration

  • `pylint`
  • `pylint`
  • `isort`
  • `isort`

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_model matching (#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 @overload and @override methods for too-many-arguments checks (#8954)
  • Lexer start of line is false only for Mode::Expression (#8880)
  • Mark pydantic_settings.BaseSettings as having default copy semantics (#8793)
  • Respect dictionary unpacking in NamedTuple assignments (#8810)
  • Respect local subclasses in flake8-type-checking (#8768)
  • Support type alias statements in simple statement positions (#8916)
  • `flake8-annotations`
  • `flake8-pie`
  • `flake8-pyi`
  • `flake8-trio`
  • `flake8-trio`
  • `isort`
  • `pep8-naming`
  • `perflint`
  • `pycodestyle`
  • `pydocstyle`
  • `pydocstyle`
  • `pylint`
  • `tryceratops`

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`
  • `flake8-pyi`

0.1.6

Preview features

  • `flake8-boolean-trap`
  • `flake8-pie`
  • `flake8-pie`
  • `flake8-pie`
  • `flake8-quotes`
  • `pycodestyle`
  • `pycodestyle`
  • `pyflakes`
  • `pylint`
  • `pylint`
  • `refurb`
  • `refurb`

Rule changes

  • `flake8-annotations`
  • `flake8-future-annotations`
  • `flake8-implicit-namespace-package`
  • `pydocstyle`
  • `pyupgrade`

Formatter

  • Fix instability in await formatting 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`
  • `pep8-naming`
  • `pydocstyle`

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 EM fixes (#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_CHECKING blocks imported from typing_extensions or _typeshed (#8429)
  • Treat display as a builtin in IPython (#8707)
  • Avoid FURB113 autofix 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`
  • `flake8-trio`
  • `flake8-trio`
  • `flake8-trio`
  • `flake8-trio`
  • `refurb`
  • Flag all comparisons against builtin types in E721 (#8491)
  • Make SIM118 fix as safe when the expression is a known dictionary (#8525)

Formatter

  • Fix multiline lambda expression statement formatting (#8466)

CLI

  • Add hidden --extension to override inference of source type from file extension (#8373)

Configuration

  • Account for selector specificity when merging extend_unsafe_fixes and override extend_safe_fixes (#8444)
  • Add support for disabling cache with RUFF_NO_CACHE environment variable (#8538)

Bug fixes

  • `E721`
  • Allow collapsed-ellipsis bodies in other statements (#8499)
  • Avoid D301 autofix for u prefixed strings (#8495)
  • Only flag flake8-trio rules when trio import is present (#8550)
  • Reject more syntactically invalid Python programs (#8524)
  • Avoid raising TRIO115 violations for trio.sleep(...) calls with non-number values (#8532)
  • Fix F841 false 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-python over target-version (#8513)
  • Add singleton escape hatch to B008 documentation (#8501)
  • Fix tab configuration docs (#8502)

0.1.4

Preview features

  • `flake8-trio`
  • `numpy`
  • `pylint`
  • `pylint`
  • `pylint`
  • `pyupgrade`
  • `refurb`
  • Detect confusable Unicode-to-Unicode units in RUF001, RUF002, and RUF003 (#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-length option to format command (#8363)
  • Avoid parenthesizing unsplittable because of comments (#8431)

CLI

  • Add --output-format to ruff rule and ruff linter (#8203)

Bug fixes

  • Respect --force-exclude in lint.exclude and format.exclude (#8393)
  • Respect --extend-per-file-ignores on the CLI (#8329)
  • Extend bad-dunder-method-name to permit __index__ (#8300)
  • Fix panic with 8 in octal escape (#8356)
  • Avoid raising D300 when both triple quote styles are present (#8462)
  • Consider unterminated f-strings in FStringRanges (#8154)
  • Avoid including literal shell=True for truthy, non-True diagnostics (#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 NamedTuple rewrite 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 PLE1307 was raised when formatting %c with characters (#8407)
  • Remove unicode flag from comparable (#8440)
  • Improve B015 message (#8295)
  • Use fixedOverflowWidgets for playground popover (#8458)
  • Mark byte_bounds as a non-backwards-compatible NumPy 2.0 change (#8474)

Internals

  • Add a dedicated cache directory per Ruff version (#8333)
  • Allow selective caching for --fix and --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, True and False (#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 isort settings (#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-line is true (#8244)
  • Use SourceKind::diff for formatter (#8240)
  • Fix fmt:off with trailing child comment (#8234)
  • Formatter parentheses support for IpyEscapeCommand (#8207)

Linter

  • `pylint`
  • Match rule prefixes from external codes setting in unused-noqa (#8177)
  • Use line-length setting for isort in lieu of pycodestyle.max-line-length (#8235)
  • Update fix for unnecessary-paren-on-raise-exception to 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 external option to unused-noqa documentation (#8171)
  • Add title attribute to icons (#8060)
  • Clarify unsafe case in RSE102 (#8256)
  • Fix skipping formatting examples (#8210)
  • docs: fix name of magic-trailing-comma option 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`
  • `pylint`
  • `pylint`
  • `refurb`
  • Add fix for E223, E224, and E242 (#8143)
  • Add fix for E225, E226, E227, and E228 (#8136)
  • Add fix for E252 (#8142)
  • Add fix for E261 (#8114)
  • Add fix for E273 and E274 (#8144)
  • Add fix for E275 (#8133)
  • Update SIM401 to catch ternary operations (#7415)
  • Update E721 to allow is and is not for direct type comparisons (#7905)

Rule changes

  • Add backports.strenum to deprecated-imports (#8113)
  • Update SIM112 to ignore https_proxy, http_proxy, and no_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-ending default to auto (#8057)
  • Respect parenthesized generators in has_own_parentheses (#8100)
  • Add caching to formatter (#8089)
  • Remove --line-length option from format command (#8131)
  • Add formatter to line-length documentation (#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 format command in help menus (#8167)
  • Add ruff version command with long version display (#8034)

Configuration

  • New pycodestyle.max-line-length option (#8039)

Bug fixes

  • Detect sys.version_info slices in outdated-version-block (#8112)
  • Avoid if-else simplification for TYPE_CHECKING blocks (#8072)
  • Avoid false-positive print separator diagnostic with starred argument (#8079)

Documentation

  • Fix message for too-many-arguments lint (#8092)
  • Fix extend-unsafe-fixes and extend-safe-fixes example (#8139)
  • Add links to flake8-import-conventions options (#8115)
  • Rework the documentation to incorporate the Ruff formatter (#7732)
  • Fix Options JSON schema description (#8081)
  • Fix typo (pytext -> pytest) (#8117)
  • Improve magic-value-comparison example 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].exclude options (#8000)
  • Respect tab-size setting in formatter (#8006)
  • Add lint.preview (#8002)

Preview features

  • `pylint`
  • `pylint`
  • `pylint`
  • `pylint`
  • `pylint`
  • 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-version to ruff format (#8055)
  • Skip over parentheses when detecting in keyword (#8054)
  • Add --diff option to ruff format (#7937)
  • Insert newline after nested function or class statements (#7946)
  • Use pass over 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-name for _ (#8015)
  • Remove Python 2-only methods from URLOpen audit (#8047)
  • Use set bracket replacement for iteration-over-set to preserve whitespace and comments (#8001)

Documentation

  • Update tutorial to match revised Ruff defaults (#8066)
  • Update rule B005 docs (#8028)
  • Update GitHub actions example in docs to use --output-format (#8014)
  • Document lint.preview and format.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 format setting has been removed (#7984)
    • The format setting cannot be used to configure the output format, use output-format instead
    • The RUFF_FORMAT environment variable is ignored, use RUFF_OUTPUT_FORMAT instead
    • The --format option has been removed from ruff check, use --output-format instead

Rule changes

  • Extend reimplemented-starmap (FURB140) to catch calls with a single and starred argument (#7768)
  • Improve cases covered by RUF015 (#7848)
  • Update SIM15 to allow open followed by close (#7916)
  • Respect msgspec.Struct default-copy semantics in RUF012 (#7786)
  • Add sqlalchemy methods 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-alias to require --unsafe-fixes outside of stub files (#7836)
  • Improve fix message for UP018 (#7913)
  • Update PLW3201 to support Enum sunder names (#7987)

Preview features

  • Only show warnings for empty preview selectors when enabling rules (#7842)
  • Add unnecessary-key-check to simplify key in dct and dct[key] to dct.get(key) (#7895)
  • Add assignment-in-assert to prevent walrus expressions in assert statements (#7856)
  • `refurb`
  • `pylint`

New rules are added in preview.

Configuration

  • Add unsafe-fixes setting (#7769)
  • Add extend-safe-fixes and extend-unsafe-fixes for promoting and demoting fixes (#7841)

CLI

  • Added --unsafe-fixes option for opt-in to display and apply unsafe fixes (#7769)
  • Fix use of deprecated --format option 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 --diff to include unsafe fix hints (#7790)
  • Add notebook cell field to JSON output format (#7664)
  • Rename applicability levels to Safe, Unsafe, and Display (#7843)

Bug fixes

  • Fix bug where f-strings were allowed in match pattern literal (#7857)
  • Fix SIM110 with a yield in the condition (#7801)
  • Preserve trailing comments in C414 fixes (#7775)
  • Check sequence type before triggering unnecessary-enumerate len suggestion (#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 E251 false 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 --unfixable in ISC rules (#7917)
  • Fix edge case with PIE804 (#7922)
  • Show custom message in PTH118 for Path.joinpath with starred arguments (#7852)
  • Fix false negative in outdated-version-block when using greater than comparisons (#7920)
  • Avoid converting f-strings within Django gettext calls (#7898)
  • Fix false positive in PLR6301 (#7933)
  • Treat type aliases as typing-only expressions e.g. resolves false positive in TCH004 (#7968)
  • Resolve cache-dir relative 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 coalesce keyword (#7876)

Documentation

  • Document reimplemented-starmap performance effects (#7846)
  • Default to following the system dark/light mode (#7888)
  • Add documentation for fixes (#7901)
  • Fix typo in docs of PLR6301 (#7831)
  • Update UP038 docs 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 FURB177 example (#7832)

Formatter

  • Less scary ruff format message (#7867)
  • Remove spaces from import statements (#7859)
  • Formatter quoting for f-strings with triple quotes (#7826)
  • Update ruff_python_formatter generate.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 Fix action (#7824)