Compare commits
2 Commits
alex/into_
...
0.14.3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8737a2d5f5 | ||
|
|
3be3a10a2f |
55
CHANGELOG.md
55
CHANGELOG.md
@@ -1,5 +1,60 @@
|
||||
# Changelog
|
||||
|
||||
## 0.14.3
|
||||
|
||||
Released on 2025-10-30.
|
||||
|
||||
### Preview features
|
||||
|
||||
- Respect `--output-format` with `--watch` ([#21097](https://github.com/astral-sh/ruff/pull/21097))
|
||||
- \[`pydoclint`\] Fix false positive on explicit exception re-raising (`DOC501`, `DOC502`) ([#21011](https://github.com/astral-sh/ruff/pull/21011))
|
||||
- \[`pyflakes`\] Revert to stable behavior if imports for module lie in alternate branches for `F401` ([#20878](https://github.com/astral-sh/ruff/pull/20878))
|
||||
- \[`pylint`\] Implement `stop-iteration-return` (`PLR1708`) ([#20733](https://github.com/astral-sh/ruff/pull/20733))
|
||||
- \[`ruff`\] Add support for additional eager conversion patterns (`RUF065`) ([#20657](https://github.com/astral-sh/ruff/pull/20657))
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- Fix finding keyword range for clause header after statement ending with semicolon ([#21067](https://github.com/astral-sh/ruff/pull/21067))
|
||||
- Fix syntax error false positive on nested alternative patterns ([#21104](https://github.com/astral-sh/ruff/pull/21104))
|
||||
- \[`ISC001`\] Fix panic when string literals are unclosed ([#21034](https://github.com/astral-sh/ruff/pull/21034))
|
||||
- \[`flake8-django`\] Apply `DJ001` to annotated fields ([#20907](https://github.com/astral-sh/ruff/pull/20907))
|
||||
- \[`flake8-pyi`\] Fix `PYI034` to not trigger on metaclasses (`PYI034`) ([#20881](https://github.com/astral-sh/ruff/pull/20881))
|
||||
- \[`flake8-type-checking`\] Fix `TC003` false positive with `future-annotations` ([#21125](https://github.com/astral-sh/ruff/pull/21125))
|
||||
- \[`pyflakes`\] Fix false positive for `__class__` in lambda expressions within class definitions (`F821`) ([#20564](https://github.com/astral-sh/ruff/pull/20564))
|
||||
- \[`pyupgrade`\] Fix false positive for `TypeVar` with default on Python \<3.13 (`UP046`,`UP047`) ([#21045](https://github.com/astral-sh/ruff/pull/21045))
|
||||
|
||||
### Rule changes
|
||||
|
||||
- Add missing docstring sections to the numpy list ([#20931](https://github.com/astral-sh/ruff/pull/20931))
|
||||
- \[`airflow`\] Extend `airflow.models..Param` check (`AIR311`) ([#21043](https://github.com/astral-sh/ruff/pull/21043))
|
||||
- \[`airflow`\] Warn that `airflow....DAG.create_dagrun` has been removed (`AIR301`) ([#21093](https://github.com/astral-sh/ruff/pull/21093))
|
||||
- \[`refurb`\] Preserve digit separators in `Decimal` constructor (`FURB157`) ([#20588](https://github.com/astral-sh/ruff/pull/20588))
|
||||
|
||||
### Server
|
||||
|
||||
- Avoid sending an unnecessary "clear diagnostics" message for clients supporting pull diagnostics ([#21105](https://github.com/astral-sh/ruff/pull/21105))
|
||||
|
||||
### Documentation
|
||||
|
||||
- \[`flake8-bandit`\] Fix correct example for `S308` ([#21128](https://github.com/astral-sh/ruff/pull/21128))
|
||||
|
||||
### Other changes
|
||||
|
||||
- Clearer error message when `line-length` goes beyond threshold ([#21072](https://github.com/astral-sh/ruff/pull/21072))
|
||||
|
||||
### Contributors
|
||||
|
||||
- [@danparizher](https://github.com/danparizher)
|
||||
- [@jvacek](https://github.com/jvacek)
|
||||
- [@ntBre](https://github.com/ntBre)
|
||||
- [@augustelalande](https://github.com/augustelalande)
|
||||
- [@prakhar1144](https://github.com/prakhar1144)
|
||||
- [@TaKO8Ki](https://github.com/TaKO8Ki)
|
||||
- [@dylwil3](https://github.com/dylwil3)
|
||||
- [@fatelei](https://github.com/fatelei)
|
||||
- [@ShaharNaveh](https://github.com/ShaharNaveh)
|
||||
- [@Lee-W](https://github.com/Lee-W)
|
||||
|
||||
## 0.14.2
|
||||
|
||||
Released on 2025-10-23.
|
||||
|
||||
6
Cargo.lock
generated
6
Cargo.lock
generated
@@ -2835,7 +2835,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ruff"
|
||||
version = "0.14.2"
|
||||
version = "0.14.3"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"argfile",
|
||||
@@ -3092,7 +3092,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ruff_linter"
|
||||
version = "0.14.2"
|
||||
version = "0.14.3"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"anyhow",
|
||||
@@ -3447,7 +3447,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ruff_wasm"
|
||||
version = "0.14.2"
|
||||
version = "0.14.3"
|
||||
dependencies = [
|
||||
"console_error_panic_hook",
|
||||
"console_log",
|
||||
|
||||
@@ -147,8 +147,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.14.2/install.sh | sh
|
||||
powershell -c "irm https://astral.sh/ruff/0.14.2/install.ps1 | iex"
|
||||
curl -LsSf https://astral.sh/ruff/0.14.3/install.sh | sh
|
||||
powershell -c "irm https://astral.sh/ruff/0.14.3/install.ps1 | iex"
|
||||
```
|
||||
|
||||
You can also install Ruff via [Homebrew](https://formulae.brew.sh/formula/ruff), [Conda](https://anaconda.org/conda-forge/ruff),
|
||||
@@ -181,7 +181,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.14.2
|
||||
rev: v0.14.3
|
||||
hooks:
|
||||
# Run the linter.
|
||||
- id: ruff-check
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "ruff"
|
||||
version = "0.14.2"
|
||||
version = "0.14.3"
|
||||
publish = true
|
||||
authors = { workspace = true }
|
||||
edition = { workspace = true }
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "ruff_linter"
|
||||
version = "0.14.2"
|
||||
version = "0.14.3"
|
||||
publish = false
|
||||
authors = { workspace = true }
|
||||
edition = { workspace = true }
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "ruff_wasm"
|
||||
version = "0.14.2"
|
||||
version = "0.14.3"
|
||||
publish = false
|
||||
authors = { workspace = true }
|
||||
edition = { workspace = true }
|
||||
|
||||
@@ -212,7 +212,10 @@ pub fn completion<'db>(
|
||||
offset: TextSize,
|
||||
) -> Vec<Completion<'db>> {
|
||||
let parsed = parsed_module(db, file).load(db);
|
||||
if is_in_comment(&parsed, offset) || is_in_string(&parsed, offset) {
|
||||
|
||||
let tokens = tokens_start_before(parsed.tokens(), offset);
|
||||
|
||||
if is_in_comment(tokens) || is_in_string(tokens) || is_in_definition_place(db, tokens, file) {
|
||||
return vec![];
|
||||
}
|
||||
|
||||
@@ -829,8 +832,7 @@ fn find_typed_text(
|
||||
|
||||
/// Whether the given offset within the parsed module is within
|
||||
/// a comment or not.
|
||||
fn is_in_comment(parsed: &ParsedModuleRef, offset: TextSize) -> bool {
|
||||
let tokens = tokens_start_before(parsed.tokens(), offset);
|
||||
fn is_in_comment(tokens: &[Token]) -> bool {
|
||||
tokens.last().is_some_and(|t| t.kind().is_comment())
|
||||
}
|
||||
|
||||
@@ -839,8 +841,7 @@ fn is_in_comment(parsed: &ParsedModuleRef, offset: TextSize) -> bool {
|
||||
///
|
||||
/// Note that this will return `false` when positioned within an
|
||||
/// interpolation block in an f-string or a t-string.
|
||||
fn is_in_string(parsed: &ParsedModuleRef, offset: TextSize) -> bool {
|
||||
let tokens = tokens_start_before(parsed.tokens(), offset);
|
||||
fn is_in_string(tokens: &[Token]) -> bool {
|
||||
tokens.last().is_some_and(|t| {
|
||||
matches!(
|
||||
t.kind(),
|
||||
@@ -849,6 +850,29 @@ fn is_in_string(parsed: &ParsedModuleRef, offset: TextSize) -> bool {
|
||||
})
|
||||
}
|
||||
|
||||
/// If the tokens end with `class f` or `def f` we return true.
|
||||
/// If the tokens end with `class` or `def`, we return false.
|
||||
/// This is fine because we don't provide completions anyway.
|
||||
fn is_in_definition_place(db: &dyn Db, tokens: &[Token], file: File) -> bool {
|
||||
tokens
|
||||
.len()
|
||||
.checked_sub(2)
|
||||
.and_then(|i| tokens.get(i))
|
||||
.is_some_and(|t| {
|
||||
if matches!(
|
||||
t.kind(),
|
||||
TokenKind::Def | TokenKind::Class | TokenKind::Type
|
||||
) {
|
||||
true
|
||||
} else if t.kind() == TokenKind::Name {
|
||||
let source = source_text(db, file);
|
||||
&source[t.range()] == "type"
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Order completions according to the following rules:
|
||||
///
|
||||
/// 1) Names with no underscore prefix
|
||||
@@ -4058,6 +4082,83 @@ def f[T](x: T):
|
||||
test.build().contains("__repr__");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_completions_in_function_def_name() {
|
||||
let builder = completion_test_builder(
|
||||
"\
|
||||
def f<CURSOR>
|
||||
",
|
||||
);
|
||||
|
||||
builder.auto_import().build().not_contains("fabs");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_completions_in_function_def_empty_name() {
|
||||
let builder = completion_test_builder(
|
||||
"\
|
||||
def <CURSOR>
|
||||
",
|
||||
);
|
||||
|
||||
builder.auto_import().build().not_contains("fabs");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_completions_in_class_def_name() {
|
||||
let builder = completion_test_builder(
|
||||
"\
|
||||
class f<CURSOR>
|
||||
",
|
||||
);
|
||||
|
||||
builder.auto_import().build().not_contains("fabs");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_completions_in_class_def_empty_name() {
|
||||
let builder = completion_test_builder(
|
||||
"\
|
||||
class <CURSOR>
|
||||
",
|
||||
);
|
||||
|
||||
builder.auto_import().build().not_contains("fabs");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_completions_in_type_def_name() {
|
||||
let builder = completion_test_builder(
|
||||
"\
|
||||
type f<CURSOR> = int
|
||||
",
|
||||
);
|
||||
|
||||
builder.auto_import().build().not_contains("fabs");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_completions_in_maybe_type_def_name() {
|
||||
let builder = completion_test_builder(
|
||||
"\
|
||||
type f<CURSOR>
|
||||
",
|
||||
);
|
||||
|
||||
builder.auto_import().build().not_contains("fabs");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_completions_in_type_def_empty_name() {
|
||||
let builder = completion_test_builder(
|
||||
"\
|
||||
type <CURSOR>
|
||||
",
|
||||
);
|
||||
|
||||
builder.auto_import().build().not_contains("fabs");
|
||||
}
|
||||
|
||||
/// A way to create a simple single-file (named `main.py`) completion test
|
||||
/// builder.
|
||||
///
|
||||
|
||||
@@ -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.14.2-alpine
|
||||
name: ghcr.io/astral-sh/ruff:0.14.3-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.14.2
|
||||
rev: v0.14.3
|
||||
hooks:
|
||||
# Run the linter.
|
||||
- id: ruff-check
|
||||
@@ -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.14.2
|
||||
rev: v0.14.3
|
||||
hooks:
|
||||
# Run the linter.
|
||||
- id: ruff-check
|
||||
@@ -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.14.2
|
||||
rev: v0.14.3
|
||||
hooks:
|
||||
# Run the linter.
|
||||
- id: ruff-check
|
||||
|
||||
@@ -369,7 +369,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.14.2
|
||||
rev: v0.14.3
|
||||
hooks:
|
||||
# Run the linter.
|
||||
- id: ruff
|
||||
|
||||
@@ -4,7 +4,7 @@ build-backend = "maturin"
|
||||
|
||||
[project]
|
||||
name = "ruff"
|
||||
version = "0.14.2"
|
||||
version = "0.14.3"
|
||||
description = "An extremely fast Python linter and code formatter, written in Rust."
|
||||
authors = [{ name = "Astral Software Inc.", email = "hey@astral.sh" }]
|
||||
readme = "README.md"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "scripts"
|
||||
version = "0.14.2"
|
||||
version = "0.14.3"
|
||||
description = ""
|
||||
authors = ["Charles Marsh <charlie.r.marsh@gmail.com>"]
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ project_root="$(dirname "$script_root")"
|
||||
echo "Updating metadata with rooster..."
|
||||
cd "$project_root"
|
||||
uvx --python 3.12 --isolated -- \
|
||||
rooster@0.1.0 release "$@"
|
||||
rooster@0.1.1 release "$@"
|
||||
|
||||
echo "Updating lockfile..."
|
||||
cargo update -p ruff
|
||||
|
||||
Reference in New Issue
Block a user