Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Detect SIM910 when using variadic keyword arguments, i.e., **kwargs #13503

Merged
merged 1 commit into from
Sep 25, 2024

Conversation

zanieb
Copy link
Member

@zanieb zanieb commented Sep 24, 2024

Closes #13493

@zanieb zanieb added the bug Something isn't working label Sep 24, 2024
@zanieb zanieb force-pushed the zb/sim910-dict branch 2 times, most recently from cfdf6b5 to 60b87df Compare September 24, 2024 14:12
Copy link
Contributor

github-actions bot commented Sep 24, 2024

ruff-ecosystem results

Linter (stable)

ℹ️ ecosystem check detected linter changes. (+49 -0 violations, +4 -0 fixes in 7 projects; 47 projects unchanged)

apache/airflow (+4 -0 violations, +0 -0 fixes)

ruff check --no-cache --exit-zero --ignore RUF9 --output-format concise --no-preview --select ALL

+ airflow/providers/amazon/aws/secrets/secrets_manager.py:173:29: SIM910 [*] Use `kwargs.get("profile_name")` instead of `kwargs.get("profile_name", None)`
+ airflow/providers/amazon/aws/secrets/systems_manager.py:107:29: SIM910 [*] Use `kwargs.get("profile_name")` instead of `kwargs.get("profile_name", None)`
+ tests/conftest.py:954:28: SIM910 [*] Use `kwargs.get("default_args")` instead of `kwargs.get("default_args", None)`
+ tests/providers/elasticsearch/log/elasticmock/utilities/__init__.py:88:32: SIM910 [*] Use `kwargs.get("body")` instead of `kwargs.get("body", None)`

apache/superset (+0 -0 violations, +2 -0 fixes)

ruff check --no-cache --exit-zero --ignore RUF9 --output-format concise --no-preview --select ALL

- superset/db_engine_specs/presto.py:650:13: SIM118 Use `key in dict` instead of `key in dict.keys()`
+ superset/db_engine_specs/presto.py:650:13: SIM118 [*] Use `key in dict` instead of `key in dict.keys()`

bokeh/bokeh (+2 -0 violations, +2 -0 fixes)

ruff check --no-cache --exit-zero --ignore RUF9 --output-format concise --no-preview --select ALL

- src/bokeh/plotting/_figure.py:193:13: SIM118 Use `key in dict` instead of `key in dict.keys()`
+ src/bokeh/plotting/_figure.py:193:13: SIM118 [*] Use `key in dict` instead of `key in dict.keys()`
+ src/bokeh/plotting/contour.py:205:17: SIM910 [*] Use `visuals.get("line_color")` instead of `visuals.get("line_color", None)`
+ src/bokeh/plotting/contour.py:222:17: SIM910 [*] Use `visuals.get("fill_color")` instead of `visuals.get("fill_color", None)`

milvus-io/pymilvus (+37 -0 violations, +0 -0 fixes)

+ pymilvus/bulk_writer/local_bulk_writer.py:113:21: SIM910 [*] Use `kwargs.get("call_back")` instead of `kwargs.get("call_back", None)`
+ pymilvus/client/asynch.py:108:18: SIM910 [*] Use `kwargs.get("timeout")` instead of `kwargs.get("timeout", None)`
+ pymilvus/client/grpc_handler.py:1255:23: SIM910 [*] Use `kwargs.get("_callback")` instead of `kwargs.get("_callback", None)`
+ pymilvus/client/grpc_handler.py:128:13: SIM910 [*] Use `kwargs.get("user")` instead of `kwargs.get("user", None)`
+ pymilvus/client/grpc_handler.py:129:13: SIM910 [*] Use `kwargs.get("password")` instead of `kwargs.get("password", None)`
+ pymilvus/client/grpc_handler.py:130:13: SIM910 [*] Use `kwargs.get("token")` instead of `kwargs.get("token", None)`
+ pymilvus/client/grpc_handler.py:1464:23: SIM910 [*] Use `kwargs.get("_callback")` instead of `kwargs.get("_callback", None)`
+ pymilvus/client/grpc_handler.py:1991:23: SIM910 [*] Use `kwargs.get("_callback")` instead of `kwargs.get("_callback", None)`
+ pymilvus/client/grpc_handler.py:473:18: SIM910 [*] Use `kwargs.get("schema")` instead of `kwargs.get("schema", None)`
+ pymilvus/client/grpc_handler.py:570:22: SIM910 [*] Use `kwargs.get("_callback")` instead of `kwargs.get("_callback", None)`
+ pymilvus/client/grpc_handler.py:602:28: SIM910 [*] Use `kwargs.get("param_name")` instead of `kwargs.get("param_name", None)`
+ pymilvus/client/grpc_handler.py:607:22: SIM910 [*] Use `kwargs.get("_callback")` instead of `kwargs.get("_callback", None)`
+ pymilvus/client/grpc_handler.py:667:22: SIM910 [*] Use `kwargs.get("_callback")` instead of `kwargs.get("_callback", None)`
+ pymilvus/client/grpc_handler.py:730:24: SIM910 [*] Use `kwargs.get("_callback")` instead of `kwargs.get("_callback", None)`
+ pymilvus/client/grpc_handler.py:749:24: SIM910 [*] Use `kwargs.get("_callback")` instead of `kwargs.get("_callback", None)`
+ pymilvus/client/grpc_handler.py:784:33: SIM910 [*] Use `kwargs.get("guarantee_timestamp")` instead of `kwargs.get("guarantee_timestamp", None)`
+ pymilvus/client/grpc_handler.py:820:33: SIM910 [*] Use `kwargs.get("guarantee_timestamp")` instead of `kwargs.get("guarantee_timestamp", None)`
+ pymilvus/client/grpc_handler.py:90:22: SIM910 [*] Use `kwargs.get("user")` instead of `kwargs.get("user", None)`
+ pymilvus/client/grpc_handler.py:92:36: SIM910 [*] Use `kwargs.get("db_name")` instead of `kwargs.get("db_name", None)`
+ pymilvus/client/grpc_handler.py:980:23: SIM910 [*] Use `kwargs.get("_callback")` instead of `kwargs.get("_callback", None)`
+ pymilvus/client/prepare.py:1052:17: SIM910 [*] Use `kwargs.get("limit")` instead of `kwargs.get("limit", None)`
+ pymilvus/client/prepare.py:1056:18: SIM910 [*] Use `kwargs.get("offset")` instead of `kwargs.get("offset", None)`
+ pymilvus/client/prepare.py:1135:25: SIM910 [*] Use `kwargs.get("channel_names")` instead of `kwargs.get("channel_names", None)`
+ pymilvus/client/prepare.py:813:12: SIM910 [*] Use `kwargs.get(RANK_GROUP_SCORER)` instead of `kwargs.get(RANK_GROUP_SCORER, None)`
+ pymilvus/client/prepare.py:822:12: SIM910 [*] Use `kwargs.get(GROUP_BY_FIELD)` instead of `kwargs.get(GROUP_BY_FIELD, None)`
+ pymilvus/client/prepare.py:831:12: SIM910 [*] Use `kwargs.get(GROUP_SIZE)` instead of `kwargs.get(GROUP_SIZE, None)`
+ pymilvus/client/prepare.py:840:12: SIM910 [*] Use `kwargs.get(GROUP_STRICT_SIZE)` instead of `kwargs.get(GROUP_STRICT_SIZE, None)`
+ pymilvus/client/prepare.py:92:26: SIM910 [*] Use `kwargs.get("num_partitions")` instead of `kwargs.get("num_partitions", None)`
+ pymilvus/decorators.py:170:21: SIM910 [*] Use `kwargs.get("log_level")` instead of `kwargs.get("log_level", None)`
+ pymilvus/decorators.py:171:22: SIM910 [*] Use `kwargs.get("client_request_id")` instead of `kwargs.get("client_request_id", None)`
+ pymilvus/decorators.py:56:24: SIM910 [*] Use `kwargs.get("timeout")` instead of `kwargs.get("timeout", None)`
+ pymilvus/decorators.py:57:28: SIM910 [*] Use `kwargs.get("retry_times")` instead of `kwargs.get("retry_times", None)`
+ pymilvus/orm/collection.py:188:51: SIM910 [*] Use `kwargs.get("auto_id")` instead of `kwargs.get("auto_id", None)`
+ pymilvus/orm/schema.py:324:30: SIM910 [*] Use `kwargs.get("default_value")` instead of `kwargs.get("default_value", None)`
... 3 additional changes omitted for project

mlflow/mlflow (+2 -0 violations, +0 -0 fixes)

+ mlflow/openai/_openai_autolog.py:203:25: SIM910 [*] Use `kwargs.get("model")` instead of `kwargs.get("model", None)`
+ mlflow/pytorch/_pytorch_autolog.py:52:53: SIM910 [*] Use `kwargs.get("global_step")` instead of `kwargs.get("global_step", None)`

reflex-dev/reflex (+2 -0 violations, +0 -0 fixes)

+ reflex/components/datadisplay/dataeditor.py:332:16: SIM910 [*] Use `props.get("rows")` instead of `props.get("rows", None)`
+ reflex/vars/base.py:242:24: SIM910 [*] Use `kwargs.get("_js_expr")` instead of `kwargs.get("_js_expr", None)`

zulip/zulip (+2 -0 violations, +0 -0 fixes)

ruff check --no-cache --exit-zero --ignore RUF9 --output-format concise --no-preview --select ALL

+ corporate/tests/test_stripe.py:652:41: SIM910 [*] Use `kwargs.get("remote_server_plan_start_date")` instead of `kwargs.get("remote_server_plan_start_date", None)`
+ zerver/lib/test_classes.py:1897:37: SIM910 [*] Use `kwargs.get("mentioned_user_group_id")` instead of `kwargs.get("mentioned_user_group_id", None)`

Changes by rule (2 rules affected)

code total + violation - violation + fix - fix
SIM910 49 49 0 0 0
SIM118 4 0 0 4 0

Linter (preview)

ℹ️ ecosystem check detected linter changes. (+49 -0 violations, +4 -0 fixes in 7 projects; 47 projects unchanged)

apache/airflow (+4 -0 violations, +0 -0 fixes)

ruff check --no-cache --exit-zero --ignore RUF9 --output-format concise --preview --select ALL

+ airflow/providers/amazon/aws/secrets/secrets_manager.py:173:29: SIM910 [*] Use `kwargs.get("profile_name")` instead of `kwargs.get("profile_name", None)`
+ airflow/providers/amazon/aws/secrets/systems_manager.py:107:29: SIM910 [*] Use `kwargs.get("profile_name")` instead of `kwargs.get("profile_name", None)`
+ tests/conftest.py:954:28: SIM910 [*] Use `kwargs.get("default_args")` instead of `kwargs.get("default_args", None)`
+ tests/providers/elasticsearch/log/elasticmock/utilities/__init__.py:88:32: SIM910 [*] Use `kwargs.get("body")` instead of `kwargs.get("body", None)`

apache/superset (+0 -0 violations, +2 -0 fixes)

ruff check --no-cache --exit-zero --ignore RUF9 --output-format concise --preview --select ALL

- superset/db_engine_specs/presto.py:650:13: SIM118 Use `key in dict` instead of `key in dict.keys()`
+ superset/db_engine_specs/presto.py:650:13: SIM118 [*] Use `key in dict` instead of `key in dict.keys()`

bokeh/bokeh (+2 -0 violations, +2 -0 fixes)

ruff check --no-cache --exit-zero --ignore RUF9 --output-format concise --preview --select ALL

- src/bokeh/plotting/_figure.py:193:13: SIM118 Use `key in dict` instead of `key in dict.keys()`
+ src/bokeh/plotting/_figure.py:193:13: SIM118 [*] Use `key in dict` instead of `key in dict.keys()`
+ src/bokeh/plotting/contour.py:205:17: SIM910 [*] Use `visuals.get("line_color")` instead of `visuals.get("line_color", None)`
+ src/bokeh/plotting/contour.py:222:17: SIM910 [*] Use `visuals.get("fill_color")` instead of `visuals.get("fill_color", None)`

milvus-io/pymilvus (+37 -0 violations, +0 -0 fixes)

ruff check --no-cache --exit-zero --ignore RUF9 --output-format concise --preview

+ pymilvus/bulk_writer/local_bulk_writer.py:113:21: SIM910 [*] Use `kwargs.get("call_back")` instead of `kwargs.get("call_back", None)`
+ pymilvus/client/asynch.py:108:18: SIM910 [*] Use `kwargs.get("timeout")` instead of `kwargs.get("timeout", None)`
+ pymilvus/client/grpc_handler.py:1255:23: SIM910 [*] Use `kwargs.get("_callback")` instead of `kwargs.get("_callback", None)`
+ pymilvus/client/grpc_handler.py:128:13: SIM910 [*] Use `kwargs.get("user")` instead of `kwargs.get("user", None)`
+ pymilvus/client/grpc_handler.py:129:13: SIM910 [*] Use `kwargs.get("password")` instead of `kwargs.get("password", None)`
+ pymilvus/client/grpc_handler.py:130:13: SIM910 [*] Use `kwargs.get("token")` instead of `kwargs.get("token", None)`
+ pymilvus/client/grpc_handler.py:1464:23: SIM910 [*] Use `kwargs.get("_callback")` instead of `kwargs.get("_callback", None)`
+ pymilvus/client/grpc_handler.py:1991:23: SIM910 [*] Use `kwargs.get("_callback")` instead of `kwargs.get("_callback", None)`
+ pymilvus/client/grpc_handler.py:473:18: SIM910 [*] Use `kwargs.get("schema")` instead of `kwargs.get("schema", None)`
+ pymilvus/client/grpc_handler.py:570:22: SIM910 [*] Use `kwargs.get("_callback")` instead of `kwargs.get("_callback", None)`
+ pymilvus/client/grpc_handler.py:602:28: SIM910 [*] Use `kwargs.get("param_name")` instead of `kwargs.get("param_name", None)`
+ pymilvus/client/grpc_handler.py:607:22: SIM910 [*] Use `kwargs.get("_callback")` instead of `kwargs.get("_callback", None)`
+ pymilvus/client/grpc_handler.py:667:22: SIM910 [*] Use `kwargs.get("_callback")` instead of `kwargs.get("_callback", None)`
+ pymilvus/client/grpc_handler.py:730:24: SIM910 [*] Use `kwargs.get("_callback")` instead of `kwargs.get("_callback", None)`
+ pymilvus/client/grpc_handler.py:749:24: SIM910 [*] Use `kwargs.get("_callback")` instead of `kwargs.get("_callback", None)`
+ pymilvus/client/grpc_handler.py:784:33: SIM910 [*] Use `kwargs.get("guarantee_timestamp")` instead of `kwargs.get("guarantee_timestamp", None)`
+ pymilvus/client/grpc_handler.py:820:33: SIM910 [*] Use `kwargs.get("guarantee_timestamp")` instead of `kwargs.get("guarantee_timestamp", None)`
+ pymilvus/client/grpc_handler.py:90:22: SIM910 [*] Use `kwargs.get("user")` instead of `kwargs.get("user", None)`
+ pymilvus/client/grpc_handler.py:92:36: SIM910 [*] Use `kwargs.get("db_name")` instead of `kwargs.get("db_name", None)`
+ pymilvus/client/grpc_handler.py:980:23: SIM910 [*] Use `kwargs.get("_callback")` instead of `kwargs.get("_callback", None)`
+ pymilvus/client/prepare.py:1052:17: SIM910 [*] Use `kwargs.get("limit")` instead of `kwargs.get("limit", None)`
+ pymilvus/client/prepare.py:1056:18: SIM910 [*] Use `kwargs.get("offset")` instead of `kwargs.get("offset", None)`
+ pymilvus/client/prepare.py:1135:25: SIM910 [*] Use `kwargs.get("channel_names")` instead of `kwargs.get("channel_names", None)`
+ pymilvus/client/prepare.py:813:12: SIM910 [*] Use `kwargs.get(RANK_GROUP_SCORER)` instead of `kwargs.get(RANK_GROUP_SCORER, None)`
+ pymilvus/client/prepare.py:822:12: SIM910 [*] Use `kwargs.get(GROUP_BY_FIELD)` instead of `kwargs.get(GROUP_BY_FIELD, None)`
+ pymilvus/client/prepare.py:831:12: SIM910 [*] Use `kwargs.get(GROUP_SIZE)` instead of `kwargs.get(GROUP_SIZE, None)`
+ pymilvus/client/prepare.py:840:12: SIM910 [*] Use `kwargs.get(GROUP_STRICT_SIZE)` instead of `kwargs.get(GROUP_STRICT_SIZE, None)`
+ pymilvus/client/prepare.py:92:26: SIM910 [*] Use `kwargs.get("num_partitions")` instead of `kwargs.get("num_partitions", None)`
+ pymilvus/decorators.py:170:21: SIM910 [*] Use `kwargs.get("log_level")` instead of `kwargs.get("log_level", None)`
+ pymilvus/decorators.py:171:22: SIM910 [*] Use `kwargs.get("client_request_id")` instead of `kwargs.get("client_request_id", None)`
+ pymilvus/decorators.py:56:24: SIM910 [*] Use `kwargs.get("timeout")` instead of `kwargs.get("timeout", None)`
+ pymilvus/decorators.py:57:28: SIM910 [*] Use `kwargs.get("retry_times")` instead of `kwargs.get("retry_times", None)`
+ pymilvus/orm/collection.py:188:51: SIM910 [*] Use `kwargs.get("auto_id")` instead of `kwargs.get("auto_id", None)`
+ pymilvus/orm/schema.py:324:30: SIM910 [*] Use `kwargs.get("default_value")` instead of `kwargs.get("default_value", None)`
... 3 additional changes omitted for project

mlflow/mlflow (+2 -0 violations, +0 -0 fixes)

ruff check --no-cache --exit-zero --ignore RUF9 --output-format concise --preview

+ mlflow/openai/_openai_autolog.py:203:25: SIM910 [*] Use `kwargs.get("model")` instead of `kwargs.get("model", None)`
+ mlflow/pytorch/_pytorch_autolog.py:52:53: SIM910 [*] Use `kwargs.get("global_step")` instead of `kwargs.get("global_step", None)`

reflex-dev/reflex (+2 -0 violations, +0 -0 fixes)

ruff check --no-cache --exit-zero --ignore RUF9 --output-format concise --preview

+ reflex/components/datadisplay/dataeditor.py:332:16: SIM910 [*] Use `props.get("rows")` instead of `props.get("rows", None)`
+ reflex/vars/base.py:242:24: SIM910 [*] Use `kwargs.get("_js_expr")` instead of `kwargs.get("_js_expr", None)`

zulip/zulip (+2 -0 violations, +0 -0 fixes)

ruff check --no-cache --exit-zero --ignore RUF9 --output-format concise --preview --select ALL

+ corporate/tests/test_stripe.py:652:41: SIM910 [*] Use `kwargs.get("remote_server_plan_start_date")` instead of `kwargs.get("remote_server_plan_start_date", None)`
+ zerver/lib/test_classes.py:1897:37: SIM910 [*] Use `kwargs.get("mentioned_user_group_id")` instead of `kwargs.get("mentioned_user_group_id", None)`

Changes by rule (2 rules affected)

code total + violation - violation + fix - fix
SIM910 49 49 0 0 0
SIM118 4 0 0 4 0

@zanieb
Copy link
Member Author

zanieb commented Sep 24, 2024

There are some ecosystem hits here but I don't think this needs to be gated by preview.

// ```
if let Some(kwarg_parameter) = parameters.kwarg.as_deref() {
if kwarg_parameter.name.range() == binding.range() {
return true;
Copy link
Member

@MichaReiser MichaReiser Sep 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know anything about the type checking code so I might be wrong here but doesn't this now return true for all type checkers?

Looking at the definition of is_dict it returns whatever check_types returns and so do all other is_* methods:

pub fn is_dict(binding: &Binding, semantic: &SemanticModel) -> bool {
check_type::<DictChecker>(binding, semantic)
}

But we could move this check into is_dict (and add support for *args to is_list)... but I don't know if this is the idiomatic way to do this. An alternative is to add a new T::match_kwarg that returns true or false. But it feels a bit overkill.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I see what you're saying... eek..

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved it into is_dict — I didn't want to touch the trait for this. We perform an extra statement lookup now but I don't think that's expensive.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And opened a corresponding is_tuple fix #13512

@zanieb zanieb merged commit 11f06e0 into main Sep 25, 2024
20 checks passed
@zanieb zanieb deleted the zb/sim910-dict branch September 25, 2024 15:03
zanieb added a commit that referenced this pull request Sep 25, 2024
…3512)

In #13503, we added supported for
detecting variadic keyword arguments as dictionaries, here we use the
same strategy for detecting variadic positional arguments as tuples.
netbsd-srcmastr pushed a commit to NetBSD/pkgsrc that referenced this pull request Oct 7, 2024
## 0.6.9

### Preview features

- Fix codeblock dynamic line length calculation for indented docstring examples ([#13523](astral-sh/ruff#13523))
- \[`refurb`\] Mark `FURB118` fix as unsafe ([#13613](astral-sh/ruff#13613))

### Rule changes

- \[`pydocstyle`\] Don't raise `D208` when last line is non-empty ([#13372](astral-sh/ruff#13372))
- \[`pylint`\] Preserve trivia (i.e. comments) in `PLR5501` autofix ([#13573](astral-sh/ruff#13573))

### Configuration

- \[`pyflakes`\] Add `allow-unused-imports` setting for `unused-import` rule (`F401`) ([#13601](astral-sh/ruff#13601))

### Bug fixes

- Support ruff discovery in pip build environments ([#13591](astral-sh/ruff#13591))
- \[`flake8-bugbear`\] Avoid short circuiting `B017` for multiple context managers ([#13609](astral-sh/ruff#13609))
- \[`pylint`\] Do not offer an invalid fix for `PLR1716` when the comparisons contain parenthesis ([#13527](astral-sh/ruff#13527))
- \[`pyupgrade`\] Fix `UP043` to apply to `collections.abc.Generator` and `collections.abc.AsyncGenerator` ([#13611](astral-sh/ruff#13611))
- \[`refurb`\] Fix handling of slices in tuples for `FURB118`, e.g., `x[:, 1]` ([#13518](astral-sh/ruff#13518))

### Documentation

- Update GitHub Action link to `astral-sh/ruff-action` ([#13551](astral-sh/ruff#13551))

## 0.6.8

### Preview features

- Remove unnecessary parentheses around `match case` clauses ([#13510](astral-sh/ruff#13510))
- Parenthesize overlong `if` guards in `match..case` clauses ([#13513](astral-sh/ruff#13513))
- Detect basic wildcard imports in `ruff analyze graph` ([#13486](astral-sh/ruff#13486))
- \[`pylint`\] Implement `boolean-chained-comparison` (`R1716`) ([#13435](astral-sh/ruff#13435))

### Rule changes

- \[`lake8-simplify`\] Detect `SIM910` when using variadic keyword arguments, i.e., `**kwargs` ([#13503](astral-sh/ruff#13503))
- \[`pyupgrade`\] Avoid false negatives with non-reference shadowed bindings of loop variables (`UP028`) ([#13504](astral-sh/ruff#13504))

### Bug fixes

- Detect tuples bound to variadic positional arguments i.e. `*args` ([#13512](astral-sh/ruff#13512))
- Exit gracefully on broken pipe errors ([#13485](astral-sh/ruff#13485))
- Avoid panic when analyze graph hits broken pipe ([#13484](astral-sh/ruff#13484))

### Performance

- Reuse `BTreeSets` in module resolver ([#13440](astral-sh/ruff#13440))
- Skip traversal for non-compound statements ([#13441](astral-sh/ruff#13441))

## 0.6.7

### Preview features

- Add Python version support to ruff analyze CLI ([#13426](astral-sh/ruff#13426))
- Add `exclude` support to `ruff analyze` ([#13425](astral-sh/ruff#13425))
- Fix parentheses around return type annotations ([#13381](astral-sh/ruff#13381))

### Rule changes

- \[`pycodestyle`\] Fix: Don't autofix if the first line ends in a question mark? (D400) ([#13399](astral-sh/ruff#13399))

### Bug fixes

- Respect `lint.exclude` in ruff check `--add-noqa` ([#13427](astral-sh/ruff#13427))

### Performance

- Avoid tracking module resolver files in Salsa ([#13437](astral-sh/ruff#13437))
- Use `forget` for module resolver database ([#13438](astral-sh/ruff#13438))

## 0.6.6

### Preview features

- \[`refurb`\] Skip `slice-to-remove-prefix-or-suffix` (`FURB188`) when non-trivial slice steps are present ([#13405](astral-sh/ruff#13405))
- Add a subcommand to generate dependency graphs ([#13402](astral-sh/ruff#13402))

### Formatter

- Fix placement of inline parameter comments ([#13379](astral-sh/ruff#13379))

### Server

- Fix off-by one error in the `LineIndex::offset` calculation ([#13407](astral-sh/ruff#13407))

### Bug fixes

- \[`fastapi`\] Respect FastAPI aliases in route definitions ([#13394](astral-sh/ruff#13394))
- \[`pydocstyle`\] Respect word boundaries when detecting function signature in docs ([#13388](astral-sh/ruff#13388))

### Documentation

- Add backlinks to rule overview linter ([#13368](astral-sh/ruff#13368))
- Fix documentation for editor vim plugin ALE ([#13348](astral-sh/ruff#13348))
- Fix rendering of `FURB188` docs ([#13406](astral-sh/ruff#13406))
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

SIM910 does not work with **kwargs
2 participants