diff --git a/BREAKING_CHANGES.md b/BREAKING_CHANGES.md index b698be8c0c..558ff4e169 100644 --- a/BREAKING_CHANGES.md +++ b/BREAKING_CHANGES.md @@ -1,5 +1,46 @@ # Breaking Changes +## 0.10.0 + +- **Changes to how the Python version is inferred when a `target-version` is not specified** ([#16319](https://github.com/astral-sh/ruff/pull/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.toml`or `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. + +- **Updated `TYPE_CHECKING` behavior** ([#16669](https://github.com/astral-sh/ruff/pull/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](https://github.com/astral-sh/ruff/pull/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_](https://docs.astral.sh/ruff/linter/#error-suppression) for the full specification. + +- **Avoid unnecessary parentheses around with statements with a single context manager and a trailing comment** ([#14005](https://github.com/astral-sh/ruff/pull/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](https://github.com/astral-sh/ruff/pull/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. + +- **\[`unsafe-markup-use`\]: `RUF035` has been recoded to `S704`** ([#15957](https://github.com/astral-sh/ruff/pull/15957)) + ## 0.9.0 Ruff now formats your code according to the 2025 style guide. As a result, your code might now get formatted differently. See the [changelog](./CHANGELOG.md#090) for a detailed list of changes. diff --git a/CHANGELOG.md b/CHANGELOG.md index e68d556a1c..335bd48789 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,122 @@ # Changelog +## 0.10.0 + +Check out the [blog post](https://astral.sh/blog/ruff-v0.10.0) 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](https://github.com/astral-sh/ruff/pull/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.toml`or `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. + +- **Updated `TYPE_CHECKING` behavior** ([#16669](https://github.com/astral-sh/ruff/pull/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](https://github.com/astral-sh/ruff/pull/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_](https://docs.astral.sh/ruff/linter/#error-suppression) for the full specification. + +- **Avoid unnecessary parentheses around with statements with a single context manager and a trailing comment** ([#14005](https://github.com/astral-sh/ruff/pull/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](https://github.com/astral-sh/ruff/pull/16456)) + + Alpine 3.21 was released in Dec 2024 and is used in the official Alpine-based Python images. Now the ruff:alpine image will use 3.21 instead of 3.20 and ruff:alpine3.20 will no longer be updated. + +### Deprecated Rules + +The following rules have been deprecated: + +- [`non-pep604-isinstance`](https://docs.astral.sh/ruff/rules/non-pep604-isinstance/) (`UP038`) +- [`suspicious-xmle-tree-usage`](https://docs.astral.sh/ruff/rules/suspicious-xmle-tree-usage/) (`S320`) + +### Remapped rules + +The following rules have been remapped to new rule codes: + +- \[`unsafe-markup-use`\]: `RUF035` to `S704` + +### Stabilization + +The following rules have been stabilized and are no longer in preview: + +- [`batched-without-explicit-strict`](https://docs.astral.sh/ruff/rules/batched-without-explicit-strict) (`B911`) +- [`unnecessary-dict-comprehension-for-iterable`](https://docs.astral.sh/ruff/rules/unnecessary-dict-comprehension-for-iterable) (`C420`) +- [`datetime-min-max`](https://docs.astral.sh/ruff/rules/datetime-min-max) (`DTZ901`) +- [`fast-api-unused-path-parameter`](https://docs.astral.sh/ruff/rules/fast-api-unused-path-parameter) (`FAST003`) +- [`root-logger-call`](https://docs.astral.sh/ruff/rules/root-logger-call) (`LOG015`) +- [`len-test`](https://docs.astral.sh/ruff/rules/len-test) (`PLC1802`) +- [`shallow-copy-environ`](https://docs.astral.sh/ruff/rules/shallow-copy-environ) (`PLW1507`) +- [`os-listdir`](https://docs.astral.sh/ruff/rules/os-listdir) (`PTH208`) +- [`invalid-pathlib-with-suffix`](https://docs.astral.sh/ruff/rules/invalid-pathlib-with-suffix) (`PTH210`) +- [`invalid-assert-message-literal-argument`](https://docs.astral.sh/ruff/rules/invalid-assert-message-literal-argument) (`RUF040`) +- [`unnecessary-nested-literal`](https://docs.astral.sh/ruff/rules/unnecessary-nested-literal) (`RUF041`) +- [`unnecessary-cast-to-int`](https://docs.astral.sh/ruff/rules/unnecessary-cast-to-int) (`RUF046`) +- [`map-int-version-parsing`](https://docs.astral.sh/ruff/rules/map-int-version-parsing) (`RUF048`) +- [`if-key-in-dict-del`](https://docs.astral.sh/ruff/rules/if-key-in-dict-del) (`RUF051`) +- [`unsafe-markup-use`](https://docs.astral.sh/ruff/rules/unsafe-markup-use) (`S704`). This rule has also been renamed from `RUF035`. +- [`split-static-string`](https://docs.astral.sh/ruff/rules/split-static-string) (`SIM905`) +- [`runtime-cast-value`](https://docs.astral.sh/ruff/rules/runtime-cast-value) (`TC006`) +- [`unquoted-type-alias`](https://docs.astral.sh/ruff/rules/unquoted-type-alias) (`TC007`) +- [`non-pep646-unpack`](https://docs.astral.sh/ruff/rules/non-pep646-unpack) (`UP044`) + +The following behaviors have been stabilized: + +- [`bad-staticmethod-argument`](https://docs.astral.sh/ruff/rules/bad-staticmethod-argument/) (`PLW0211`) [`invalid-first-argument-name-for-class-method`](https://docs.astral.sh/ruff/rules/invalid-first-argument-name-for-class-method/) (`N804`): `__new__` methods are now no longer flagged by `invalid-first-argument-name-for-class-method` (`N804`) but instead by `bad-staticmethod-argument` (`PLW0211`) +- [`bad-str-strip-call`](https://docs.astral.sh/ruff/rules/bad-str-strip-call/) (`PLE1310`): The rule now applies to objects which are known to have type `str` or `bytes`. +- [`blanket-noqa`](https://docs.astral.sh/ruff/rules/blanket-noqa/) (`PGH004`): Also detect blanked file-level noqa comments (and not just line level comments). +- [`custom-type-var-for-self`](https://docs.astral.sh/ruff/rules/custom-type-var-for-self/) (`PYI019`): More accurate detection of custom `TypeVars` replaceable by `Self`. The range of the diagnostic is now the full function header rather than just the return annotation. +- [`invalid-argument-name`](https://docs.astral.sh/ruff/rules/invalid-argument-name/) (`N803`): Ignore argument names of functions decorated with `typing.override` +- [`invalid-envvar-default`](https://docs.astral.sh/ruff/rules/invalid-envvar-default/) (`PLW1508`): Detect default value arguments to `os.environ.get` with invalid type. +- [`pytest-raises-with-multiple-statements`](https://docs.astral.sh/ruff/rules/pytest-raises-with-multiple-statements/) (`PT012`) [`pytest-warns-with-multiple-statements`](https://docs.astral.sh/ruff/rules/pytest-warns-with-multiple-statements/) (`PT031`): Allow `for` statements with an empty body in `pytest.raises` and `pytest.warns` `with` statements. +- [`redundant-open-modes`](https://docs.astral.sh/ruff/rules/redundant-open-modes/) (`UP015`): The diagnostic range is now the range of the redundant mode argument where it previously was the range of the entire open call. You may have to replace your `noqa` comments when suppressing `UP015`. +- [`stdlib-module-shadowing`](https://docs.astral.sh/ruff/rules/stdlib-module-shadowing/) (`A005`): Changes the default value of `lint.flake8-builtins.strict-checking` from `true` to `false`. +- [`type-none-comparison`](https://docs.astral.sh/ruff/rules/type-none-comparison/) (`FURB169`): Now also recognizes `type(expr) is type(None)` comparisons where `expr` isn't a name expression. + +The following fixes or improvements to fixes have been stabilized: + +- [`repeated-equality-comparison`](https://docs.astral.sh/ruff/rules/repeated-equality-comparison/) (`PLR1714`) ([#16685](https://github.com/astral-sh/ruff/pull/16685)) +- [`needless-bool`](https://docs.astral.sh/ruff/rules/needless-bool/) (`SIM103`) ([#16684](https://github.com/astral-sh/ruff/pull/16684)) +- [`unused-private-type-var`](https://docs.astral.sh/ruff/rules/unused-private-type-var/) (`PYI018`) ([#16682](https://github.com/astral-sh/ruff/pull/16682)) + +### Server + +- Remove logging output for `ruff.printDebugInformation` ([#16617](https://github.com/astral-sh/ruff/pull/16617)) + +### Configuration + +- \[`flake8-builtins`\] Deprecate the `builtins-` prefixed options in favor of the unprefixed options (e.g. `builtins-allowed-modules` is now deprecated in favor of `allowed-modules`) ([#16092](https://github.com/astral-sh/ruff/pull/16092)) + +### Bug fixes + +- [flake8-bandit] Fix mixed-case hash algorithm names (S324) ([#16552](https://github.com/astral-sh/ruff/pull/16552)) + +### CLI + +- [ruff] Fix `last_tag`/`commits_since_last_tag` for `version` command ([#16686](https://github.com/astral-sh/ruff/pull/16686)) + ## 0.9.10 ### Preview features @@ -1331,7 +1448,7 @@ The following fixes have been stabilized: ## 0.5.6 -Ruff 0.5.6 automatically enables linting and formatting of notebooks in *preview mode*. +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. ```toml @@ -2084,7 +2201,7 @@ To setup `ruff server` with your editor, refer to the [README.md](https://github ### Server -*This section is devoted to updates for our new language server, written in Rust.* +_This section is devoted to updates for our new language server, written in Rust._ - Enable ruff-specific source actions ([#10916](https://github.com/astral-sh/ruff/pull/10916)) - Refreshes diagnostics for open files when file configuration is changed ([#10988](https://github.com/astral-sh/ruff/pull/10988)) @@ -3491,7 +3608,7 @@ Read Ruff's new [versioning policy](https://docs.astral.sh/ruff/versioning/). - \[`refurb`\] Add `single-item-membership-test` (`FURB171`) ([#7815](https://github.com/astral-sh/ruff/pull/7815)) - \[`pylint`\] Add `and-or-ternary` (`R1706`) ([#7811](https://github.com/astral-sh/ruff/pull/7811)) -*New rules are added in [preview](https://docs.astral.sh/ruff/preview/).* +_New rules are added in [preview](https://docs.astral.sh/ruff/preview/)._ ### Configuration diff --git a/Cargo.lock b/Cargo.lock index ba9030af5f..4f03ba3d6b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2659,7 +2659,7 @@ dependencies = [ [[package]] name = "ruff" -version = "0.9.10" +version = "0.10.0" dependencies = [ "anyhow", "argfile", @@ -2894,7 +2894,7 @@ dependencies = [ [[package]] name = "ruff_linter" -version = "0.9.10" +version = "0.10.0" dependencies = [ "aho-corasick", "anyhow", @@ -3216,7 +3216,7 @@ dependencies = [ [[package]] name = "ruff_wasm" -version = "0.9.10" +version = "0.10.0" dependencies = [ "console_error_panic_hook", "console_log", diff --git a/README.md b/README.md index 55b4036c0f..2b4c9c54b4 100644 --- a/README.md +++ b/README.md @@ -149,8 +149,8 @@ curl -LsSf https://astral.sh/ruff/install.sh | sh powershell -c "irm https://astral.sh/ruff/install.ps1 | iex" # For a specific version. -curl -LsSf https://astral.sh/ruff/0.9.10/install.sh | sh -powershell -c "irm https://astral.sh/ruff/0.9.10/install.ps1 | iex" +curl -LsSf https://astral.sh/ruff/0.10.0/install.sh | sh +powershell -c "irm https://astral.sh/ruff/0.10.0/install.ps1 | iex" ``` You can also install Ruff via [Homebrew](https://formulae.brew.sh/formula/ruff), [Conda](https://anaconda.org/conda-forge/ruff), @@ -183,7 +183,7 @@ Ruff can also be used as a [pre-commit](https://pre-commit.com/) hook via [`ruff ```yaml - repo: https://github.com/astral-sh/ruff-pre-commit # Ruff version. - rev: v0.9.10 + rev: v0.10.0 hooks: # Run the linter. - id: ruff diff --git a/crates/ruff/Cargo.toml b/crates/ruff/Cargo.toml index 13665be47b..82afc1ef87 100644 --- a/crates/ruff/Cargo.toml +++ b/crates/ruff/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ruff" -version = "0.9.10" +version = "0.10.0" publish = true authors = { workspace = true } edition = { workspace = true } diff --git a/crates/ruff_linter/Cargo.toml b/crates/ruff_linter/Cargo.toml index b4c6efb672..a45170c0dd 100644 --- a/crates/ruff_linter/Cargo.toml +++ b/crates/ruff_linter/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ruff_linter" -version = "0.9.10" +version = "0.10.0" publish = false authors = { workspace = true } edition = { workspace = true } diff --git a/crates/ruff_wasm/Cargo.toml b/crates/ruff_wasm/Cargo.toml index 7e17d46041..3036cf6749 100644 --- a/crates/ruff_wasm/Cargo.toml +++ b/crates/ruff_wasm/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ruff_wasm" -version = "0.9.10" +version = "0.10.0" publish = false authors = { workspace = true } edition = { workspace = true } diff --git a/docs/integrations.md b/docs/integrations.md index 502a149abf..2920cdb419 100644 --- a/docs/integrations.md +++ b/docs/integrations.md @@ -80,7 +80,7 @@ You can add the following configuration to `.gitlab-ci.yml` to run a `ruff forma stage: build interruptible: true image: - name: ghcr.io/astral-sh/ruff:0.9.10-alpine + name: ghcr.io/astral-sh/ruff:0.10.0-alpine before_script: - cd $CI_PROJECT_DIR - ruff --version @@ -106,7 +106,7 @@ Ruff can be used as a [pre-commit](https://pre-commit.com) hook via [`ruff-pre-c ```yaml - repo: https://github.com/astral-sh/ruff-pre-commit # Ruff version. - rev: v0.9.10 + rev: v0.10.0 hooks: # Run the linter. - id: ruff @@ -119,7 +119,7 @@ To enable lint fixes, add the `--fix` argument to the lint hook: ```yaml - repo: https://github.com/astral-sh/ruff-pre-commit # Ruff version. - rev: v0.9.10 + rev: v0.10.0 hooks: # Run the linter. - id: ruff @@ -133,7 +133,7 @@ To avoid running on Jupyter Notebooks, remove `jupyter` from the list of allowed ```yaml - repo: https://github.com/astral-sh/ruff-pre-commit # Ruff version. - rev: v0.9.10 + rev: v0.10.0 hooks: # Run the linter. - id: ruff diff --git a/docs/tutorial.md b/docs/tutorial.md index 2739797f2c..d28c88c0c2 100644 --- a/docs/tutorial.md +++ b/docs/tutorial.md @@ -365,7 +365,7 @@ This tutorial has focused on Ruff's command-line interface, but Ruff can also be ```yaml - repo: https://github.com/astral-sh/ruff-pre-commit # Ruff version. - rev: v0.9.10 + rev: v0.10.0 hooks: # Run the linter. - id: ruff diff --git a/pyproject.toml b/pyproject.toml index ceaf6242e3..e523cf5ec3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "maturin" [project] name = "ruff" -version = "0.9.10" +version = "0.10.0" description = "An extremely fast Python linter and code formatter, written in Rust." authors = [{ name = "Astral Software Inc.", email = "hey@astral.sh" }] readme = "README.md" diff --git a/scripts/benchmarks/pyproject.toml b/scripts/benchmarks/pyproject.toml index e6aa99f308..1ae16bf0d7 100644 --- a/scripts/benchmarks/pyproject.toml +++ b/scripts/benchmarks/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "scripts" -version = "0.9.10" +version = "0.10.0" description = "" authors = ["Charles Marsh "]