Skip to content

Commit 6450fdc

Browse files
committed
Merge branch 'main' into claude/fix-issue-1858-UjARA
* main: (62 commits) [`refurb`] Do not add `abc.ABC` if already present (`FURB180`) (#22234) [ty] Add a new `assert-type-unspellable-subtype` diagnostic (#22815) [ty] Avoid duplicate syntax errors for `await` outside functions (#22826) [ty] Fix unary operator false-positive for constrained TypeVars (#22783) [ty] Fix binary operator false-positive for constrained TypeVars (#22782) [ty] Fix false-positive `unsupported-operator` for "symmetric" TypeVars (#22756) [`pydocstyle`] Clarify which quote styles are allowed (`D300`) (#22825) [ty] Use distributed versions of AND and OR on constraint sets (#22614) [ty] Add support for dict literals and dict() calls as default values for parameters with TypedDict types (#22161) Document `-` stdin convention in CLI help text (#22817) [ty] Make `infer_subscript_expression_types` a method on `Type` (#22731) [ty] Simplify `OverloadLiteral::spans` and `OverloadLiteral::parameter_span` (#22823) [ty] Require both `*args` and `**kwargs` when calling a `ParamSpec` callable (#22820) [ty] Handle tagged errors in conformance (#22746) Add `--color` cli option to force colored output (#22806) Identify notebooks by LSP didOpen instead of `.ipynb` file extension (#22810) [ty] Fix docstring rendering for literal blocks after doctests (#22676) [ty] Update salsa to fix out-of-order query validation (#22498) [ty] Inline cycle initial and recovery functions (#22814) [ty] Pass the generic context through the decorator (#22544) ...
2 parents 7247fb8 + 0255200 commit 6450fdc

148 files changed

Lines changed: 7481 additions & 2733 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.claude/hooks/session-start-web.sh

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#!/bin/bash
2+
set -euo pipefail
3+
4+
# Install `gh`
5+
if ! command -v gh &> /dev/null; then
6+
apt-get update -qq
7+
apt-get install -y -qq gh
8+
fi
9+
10+
# Install clippy and rustfmt for the active toolchain.
11+
rustup component add clippy rustfmt

.claude/hooks/session-start.sh

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#!/bin/bash
2+
set -euo pipefail
3+
4+
# Dispatch to web hook if running remotely
5+
if [ "${CLAUDE_CODE_REMOTE:-}" = "true" ]; then
6+
exec "$(dirname "$0")/session-start-web.sh"
7+
fi

.claude/settings.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"hooks": {
3+
"SessionStart": [
4+
{
5+
"matcher": "startup",
6+
"hooks": [
7+
{
8+
"type": "command",
9+
"command": ".claude/hooks/session-start.sh"
10+
}
11+
]
12+
}
13+
]
14+
}
15+
}

.github/workflows/ci.yaml

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -653,6 +653,7 @@ jobs:
653653
with:
654654
name: ecosystem-result
655655
path: ecosystem-result
656+
if-no-files-found: "error"
656657

657658
fuzz-ty:
658659
name: "Fuzz for new ty panics"
@@ -1019,7 +1020,8 @@ jobs:
10191020
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
10201021
with:
10211022
name: benchmarks-instrumented-ty-binary
1022-
path: target/codspeed/simulation/ruff_benchmark
1023+
path: target/codspeed
1024+
if-no-files-found: "error"
10231025
retention-days: 1
10241026

10251027
benchmarks-instrumented-ty-run:
@@ -1052,10 +1054,11 @@ jobs:
10521054
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
10531055
with:
10541056
name: benchmarks-instrumented-ty-binary
1055-
path: target/codspeed/simulation/ruff_benchmark
1057+
path: target/codspeed
10561058

10571059
- name: "Restore binary permissions"
1058-
run: chmod +x target/codspeed/simulation/ruff_benchmark/ty
1060+
# codspeed keeps changing the paths to the executable, so we have to be a bit more flexible
1061+
run: find target/codspeed -type f -exec chmod +x {} +
10591062

10601063
- name: "Run benchmarks"
10611064
uses: CodSpeedHQ/action@dbda7111f8ac363564b0c51b992d4ce76bb89f2f # v4.5.2
@@ -1106,7 +1109,8 @@ jobs:
11061109
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
11071110
with:
11081111
name: benchmarks-walltime-binary
1109-
path: target/codspeed/walltime/ruff_benchmark
1112+
path: target/codspeed
1113+
if-no-files-found: "error"
11101114
retention-days: 1
11111115

11121116
benchmarks-walltime-run:
@@ -1141,10 +1145,11 @@ jobs:
11411145
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
11421146
with:
11431147
name: benchmarks-walltime-binary
1144-
path: target/codspeed/walltime/ruff_benchmark
1148+
path: target/codspeed
11451149

11461150
- name: "Restore binary permissions"
1147-
run: chmod +x target/codspeed/walltime/ruff_benchmark/ty_walltime
1151+
# codspeed keeps changing the paths to the executable, so we have to be a bit more flexible
1152+
run: find target/codspeed -type f -exec chmod +x {} +
11481153

11491154
- name: "Run benchmarks"
11501155
uses: CodSpeedHQ/action@dbda7111f8ac363564b0c51b992d4ce76bb89f2f # v4.5.2

CHANGELOG.md

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,60 @@
11
# Changelog
22

3+
## 0.14.14
4+
5+
Released on 2026-01-22.
6+
7+
### Preview features
8+
9+
- Preserve required parentheses in lambda bodies ([#22747](https://github.com/astral-sh/ruff/pull/22747))
10+
- Combine range suppression code diagnostics ([#22613](https://github.com/astral-sh/ruff/pull/22613))
11+
- \[`airflow`\] Second positional argument to `Asset`/`Dataset` should not be a dictionary (`AIR303`) ([#22453](https://github.com/astral-sh/ruff/pull/22453))
12+
- \[`ruff`\] Detect duplicate entries in `__all__` (`RUF068`) ([#22114](https://github.com/astral-sh/ruff/pull/22114))
13+
14+
### Bug fixes
15+
16+
- \[`pyupgrade`\] Allow shadowing non-builtin bindings (`UP029`) ([#22749](https://github.com/astral-sh/ruff/pull/22749))
17+
- \[`pyupgrade`\] Apply `UP045` to string arguments of `typing.cast` ([#22320](https://github.com/astral-sh/ruff/pull/22320))
18+
- \[`flake8-pie`\] Detect duplicated declared class fields in `PIE794` ([#22717](https://github.com/astral-sh/ruff/pull/22717))
19+
20+
### Rule changes
21+
22+
- \[`flake8-pyi`\] Fix inconsistent handling of forward references for `__new__`, `__enter__`, `__aenter__` in `PYI034` ([#22798](https://github.com/astral-sh/ruff/pull/22798))
23+
- \[`flake8-pytest-style`\] Support `check` parameter in `PT011` ([#22725](https://github.com/astral-sh/ruff/pull/22725))
24+
- \[`ruff`\] Add exception for `ctypes.Structure._fields_` (`RUF012`) ([#22559](https://github.com/astral-sh/ruff/pull/22559))
25+
- Many fixes are now marked unsafe if they would remove comments:
26+
- \[`flake8-bugbear`\] [`B009`](https://github.com/astral-sh/ruff/pull/22656), [`B010`](https://github.com/astral-sh/ruff/pull/22657), [`B013`](https://github.com/astral-sh/ruff/pull/22658), [`B014`](https://github.com/astral-sh/ruff/pull/22659), [`B033`](https://github.com/astral-sh/ruff/pull/22632)
27+
- \[`flake8-simplify`\] [`SIM910`](https://github.com/astral-sh/ruff/pull/22662), [`SIM911`](https://github.com/astral-sh/ruff/pull/22661)
28+
- \[`pyupgrade`\] [`UP007`](https://github.com/astral-sh/ruff/pull/22772), [`UP039`](https://github.com/astral-sh/ruff/pull/22774), [`UP041`](https://github.com/astral-sh/ruff/pull/22773), [`UP045`](https://github.com/astral-sh/ruff/pull/22772)
29+
- \[`refurb`\] [`FURB105`](https://github.com/astral-sh/ruff/pull/22767), [`FURB116`](https://github.com/astral-sh/ruff/pull/22681), [`FURB136`](https://github.com/astral-sh/ruff/pull/22680), [`FURB140`](https://github.com/astral-sh/ruff/pull/22679), [`FURB145`](https://github.com/astral-sh/ruff/pull/22670), [`FURB154`](https://github.com/astral-sh/ruff/pull/22669), [`FURB157`](https://github.com/astral-sh/ruff/pull/22668), [`FURB164`](https://github.com/astral-sh/ruff/pull/22667),[`FURB181`](https://github.com/astral-sh/ruff/pull/22666), [`FURB188`](https://github.com/astral-sh/ruff/pull/22665)
30+
- \[`ruff`\] [`RUF019`](https://github.com/astral-sh/ruff/pull/22663), [`RUF020`](https://github.com/astral-sh/ruff/pull/22664)
31+
32+
### Documentation
33+
34+
- Add `--exit-non-zero-on-format` to formatter exit codes section ([#22761](https://github.com/astral-sh/ruff/pull/22761))
35+
- Update contributing guide for adding a new rule ([#22779](https://github.com/astral-sh/ruff/pull/22779))
36+
- \[`FastAPI`\] Document fix safety for `FAST001` ([#22655](https://github.com/astral-sh/ruff/pull/22655))
37+
- \[`flake8-async`\] Tweak explanation to focus on latency/efficiency tradeoff (`ASYNC110`) ([#22715](https://github.com/astral-sh/ruff/pull/22715))
38+
- \[`pandas-vet`\] Make example error out-of-the-box (`PD002`) ([#22561](https://github.com/astral-sh/ruff/pull/22561))
39+
- \[`refurb`\] Make the example work out of box (`FURB101`) ([#22770](https://github.com/astral-sh/ruff/pull/22770))
40+
- \[`refurb`\] Make the example work out of box (`FURB103`) ([#22769](https://github.com/astral-sh/ruff/pull/22769))
41+
42+
### Contributors
43+
44+
- [@alejsdev](https://github.com/alejsdev)
45+
- [@ntBre](https://github.com/ntBre)
46+
- [@caiquejjx](https://github.com/caiquejjx)
47+
- [@chirizxc](https://github.com/chirizxc)
48+
- [@denyszhak](https://github.com/denyszhak)
49+
- [@sjyangkevin](https://github.com/sjyangkevin)
50+
- [@MeGaGiGaGon](https://github.com/MeGaGiGaGon)
51+
- [@leandrobbraga](https://github.com/leandrobbraga)
52+
- [@MichaReiser](https://github.com/MichaReiser)
53+
- [@carljm](https://github.com/carljm)
54+
- [@amyreese](https://github.com/amyreese)
55+
- [@zsol](https://github.com/zsol)
56+
- [@harupy](https://github.com/harupy)
57+
358
## 0.14.13
459

560
Released on 2026-01-15.

CLAUDE.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,16 @@ Run tests for a specific crate:
2222
cargo nextest run -p ty_python_semantic
2323
```
2424

25-
Run a specific mdtest (use a substring of the test name):
25+
Run a single mdtest file:
2626

2727
```sh
28-
MDTEST_TEST_FILTER="<filter>" cargo nextest run -p ty_python_semantic mdtest
28+
cargo nextest run -p ty_python_semantic --test mdtest -- mdtest::<path/to/mdtest_file.md>
29+
```
30+
31+
To run a specific mdtest within a file, use a substring of the Markdown header text as `MDTEST_TEST_FILTER`. Only use this if it's necessary to isolate a single test case:
32+
33+
```sh
34+
MDTEST_TEST_FILTER="<filter>" cargo nextest run -p ty_python_semantic --test mdtest -- mdtest::<path/to/mdtest_file.md>
2935
```
3036

3137
Update snapshots after running tests:

CONTRIBUTING.md

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,10 @@ At a high level, the steps involved in adding a new lint rule are as follows:
160160
1. Create a file for your rule (e.g., `crates/ruff_linter/src/rules/flake8_bugbear/rules/assert_false.rs`).
161161

162162
1. In that file, define a violation struct (e.g., `pub struct AssertFalse`). You can grep for
163-
`#[derive(ViolationMetadata)]` to see examples.
163+
`#[derive(ViolationMetadata)]` to see examples. You also need to add a
164+
`#[violation_metadata(preview_since = "NEXT_RUFF_VERSION")]` attribute on your
165+
`ViolationMetadata` struct. This adds the rule in preview, and the version will be filled in
166+
automatically in the next release.
164167

165168
1. In that file, define a function that adds the violation to the diagnostic list as appropriate
166169
(e.g., `pub(crate) fn assert_false`) based on whatever inputs are required for the rule (e.g.,
@@ -174,8 +177,7 @@ At a high level, the steps involved in adding a new lint rule are as follows:
174177
statements, like imports) or `analyze/expression.rs` (if your rule is based on analyzing
175178
expressions, like function calls).
176179

177-
1. Map the violation struct to a rule code in `crates/ruff_linter/src/codes.rs` (e.g., `B011`). New rules
178-
should be added in `RuleGroup::Preview`.
180+
1. Map the violation struct to a rule code in `crates/ruff_linter/src/codes.rs` (e.g., `B011`).
179181

180182
1. Add proper [testing](#rule-testing-fixtures-and-snapshots) for your rule.
181183

@@ -186,8 +188,9 @@ to call your new function at the appropriate time and with the appropriate input
186188
defined therein is a Python AST visitor, which iterates over the AST, building up a semantic model,
187189
and calling out to lint rule analyzer functions as it goes.
188190

189-
If you need to inspect the AST, you can run `cargo dev print-ast` with a Python file. Grep
190-
for the `Diagnostic::new` invocations to understand how other, similar rules are implemented.
191+
If you need to inspect the AST, you can run `cargo dev print-ast` with a Python file or use the AST
192+
panel in the [playground](https://play.ruff.rs/?secondary=AST). Grep for the
193+
`Checker::report_diagnostic` invocations to understand how other, similar rules are implemented.
191194

192195
Once you're satisfied with your code, add tests for your rule
193196
(see: [rule testing](#rule-testing-fixtures-and-snapshots)), and regenerate the documentation and

Cargo.lock

Lines changed: 7 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ regex-automata = { version = "0.4.9" }
152152
rustc-hash = { version = "2.0.0" }
153153
rustc-stable-hash = { version = "0.1.2" }
154154
# When updating salsa, make sure to also update the revision in `fuzz/Cargo.toml`
155-
salsa = { git = "https://github.com/salsa-rs/salsa.git", rev = "9860ff6ca0f1f8f3a8d6b832020002790b501254", default-features = false, features = [
155+
salsa = { git = "https://github.com/salsa-rs/salsa.git", rev = "0946cbd6478cf2bddfc9ac65b3c254c1f1b1bf95", default-features = false, features = [
156156
"compact_str",
157157
"macros",
158158
"salsa_unstable",

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,8 @@ curl -LsSf https://astral.sh/ruff/install.sh | sh
150150
powershell -c "irm https://astral.sh/ruff/install.ps1 | iex"
151151

152152
# For a specific version.
153-
curl -LsSf https://astral.sh/ruff/0.14.13/install.sh | sh
154-
powershell -c "irm https://astral.sh/ruff/0.14.13/install.ps1 | iex"
153+
curl -LsSf https://astral.sh/ruff/0.14.14/install.sh | sh
154+
powershell -c "irm https://astral.sh/ruff/0.14.14/install.ps1 | iex"
155155
```
156156

157157
You can also install Ruff via [Homebrew](https://formulae.brew.sh/formula/ruff), [Conda](https://anaconda.org/conda-forge/ruff),
@@ -184,7 +184,7 @@ Ruff can also be used as a [pre-commit](https://pre-commit.com/) hook via [`ruff
184184
```yaml
185185
- repo: https://github.com/astral-sh/ruff-pre-commit
186186
# Ruff version.
187-
rev: v0.14.13
187+
rev: v0.14.14
188188
hooks:
189189
# Run the linter.
190190
- id: ruff-check

0 commit comments

Comments
 (0)