Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Add import insertion support to autofix capabilities #3787

Merged
merged 2 commits into from Mar 30, 2023

Conversation

charliermarsh
Copy link
Member

@charliermarsh charliermarsh commented Mar 28, 2023

Summary

We often have rules (and violations) that could in theory be autofixed, but that rely on the presence of an imported symbol that may or may not be available in scope.

The sys-exit-alias rule is a good example. It recommends replacing calls to the builtin exit and quit methods with calls to sys.exit. That's "easy" to autofix... as long as sys.exit is in-scope.

This PR enables rules to import symbols into the current scope in a fairly general way, enabling autofix support for rules like sys-exit-alias. Below, I've also extended autofix support for lru-cache-with-maxsize-none, which relies on making functools.cache available.

How it works

From a rule's perspective, the end-user API leans on a single get_or_import_symbol method, which returns (1) an Edit (to "insert" the symbol into the scope) and (2) the bound name of the resolved symbol (e.g., exit, if we added from sys import exit, or sys.exit, if we added import sys).

Under-the-hood, that method performs a series of lookups:

  1. First, it checks to see if sys.exit is already available in any form (e.g., from sys import exit as foo, import sys as foo); if so, it returns a reference to it.
  2. Otherwise, it checks to see if there's an import ... from for the relevant module (e.g., from sys import path). If so, it modifies that import to include the necessary symbol (from sys import path, exit). If exit is already bound to something else, it aborts and logs an error.
  3. Otherwise, it generates an edit to insert an import sys, and returns sys.exit as the bound reference.

The logic for inserting imports is crude and follows LibCST's own logic: if there are no imports, we insert at top-of-file; otherwise, we insert after the last-seen top-level import statement.

Limitations

There are a few limitations to the current approach:

  1. We don't attempt to retain import order at all. We leave that up to the isort rules (or isort itself, if you're using isort).

  2. We only respect top-level imports, so here, we'd still insert an import sys:

def f():
  from sys import path

  quit()
  1. Every individual fix (that relies on import insertion) has to go through this process. We may want to implement some sort of cache here.

Closes #835.

@github-actions
Copy link
Contributor

github-actions bot commented Mar 28, 2023

PR Check Results

Ecosystem

✅ ecosystem check detected no changes.

Benchmark

Linux

group                                      main                                   pr
-----                                      ----                                   --
linter/all-rules/large/dataset.py          1.00     17.1±0.34ms     2.4 MB/sec    1.04     17.8±0.36ms     2.3 MB/sec
linter/all-rules/numpy/ctypeslib.py        1.00      4.3±0.12ms     3.9 MB/sec    1.03      4.5±0.16ms     3.7 MB/sec
linter/all-rules/numpy/globals.py          1.00   572.2±15.38µs     5.2 MB/sec    1.00   573.5±14.79µs     5.1 MB/sec
linter/all-rules/pydantic/types.py         1.00      7.3±0.25ms     3.5 MB/sec    1.03      7.6±0.16ms     3.4 MB/sec
linter/default-rules/large/dataset.py      1.00      8.6±0.13ms     4.7 MB/sec    1.09      9.4±0.32ms     4.3 MB/sec
linter/default-rules/numpy/ctypeslib.py    1.00  1977.1±55.79µs     8.4 MB/sec    1.03      2.0±0.08ms     8.2 MB/sec
linter/default-rules/numpy/globals.py      1.00    235.8±7.58µs    12.5 MB/sec    1.03   242.3±11.21µs    12.2 MB/sec
linter/default-rules/pydantic/types.py     1.00      4.0±0.09ms     6.4 MB/sec    1.06      4.3±0.11ms     6.0 MB/sec

Windows

group                                      main                                   pr
-----                                      ----                                   --
linter/all-rules/large/dataset.py          1.00     13.7±0.17ms     3.0 MB/sec    1.00     13.7±0.18ms     3.0 MB/sec
linter/all-rules/numpy/ctypeslib.py        1.00      3.4±0.03ms     4.9 MB/sec    1.00      3.4±0.04ms     4.9 MB/sec
linter/all-rules/numpy/globals.py          1.00    358.0±6.67µs     8.2 MB/sec    1.00    357.8±3.90µs     8.2 MB/sec
linter/all-rules/pydantic/types.py         1.01      5.7±0.06ms     4.4 MB/sec    1.00      5.7±0.06ms     4.5 MB/sec
linter/default-rules/large/dataset.py      1.01      7.3±0.07ms     5.6 MB/sec    1.00      7.2±0.07ms     5.7 MB/sec
linter/default-rules/numpy/ctypeslib.py    1.01  1508.0±13.70µs    11.0 MB/sec    1.00  1494.8±18.25µs    11.1 MB/sec
linter/default-rules/numpy/globals.py      1.00    156.1±1.85µs    18.9 MB/sec    1.00    156.3±3.88µs    18.9 MB/sec
linter/default-rules/pydantic/types.py     1.01      3.2±0.03ms     7.9 MB/sec    1.00      3.2±0.04ms     8.0 MB/sec

}

/// Find the end of the last docstring.
fn match_docstring_end(body: &[Stmt]) -> Option<Location> {
Copy link
Member Author

Choose a reason for hiding this comment

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

GitHub isn't picking it up, but everything from here down is moved from rules/isort/rules/add_required_import.rs (which now uses this Importer struct).

@JonathanPlasse
Copy link
Contributor

What happens if sysis shadowed?
Do you import sys with an alias like sys_ with as many _ necessary to avoid the shadowing?

@charliermarsh
Copy link
Member Author

No, we avoid fixing if the name is already bound to something else. In practice, I think that's the least surprising behavior.

Base automatically changed from charlie/resolve-binding to main March 29, 2023 21:47
Copy link
Member

@MichaReiser MichaReiser left a comment

Choose a reason for hiding this comment

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

Nice!

Can we add a test case that demonstrates what happens if we have

if test:
	import path


exit(1)

or

import path

if test:
	pass

import numpy

// ...

exit(1)

crates/ruff/src/checkers/ast/mod.rs Outdated Show resolved Hide resolved
crates/ruff/src/cst/matchers.rs Show resolved Hide resolved
crates/ruff/src/importer.rs Outdated Show resolved Hide resolved
crates/ruff/src/autofix/helpers.rs Show resolved Hide resolved
)
}
} else {
// Case 2: No `functools` import is in scope; thus, we add `import functools`, and
Copy link
Member

Choose a reason for hiding this comment

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

why not from functools import lru_cache? that's what i'd expect and afaik that's what pycharm generally does

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah I wasn't sure what the default should be here. I was thinking that it should be rule-dependent (e.g., it makes sense to do from typing import List rather than import typing; typing.List if we need to inject from typing).

Where does PyCharm do this? When you have @cache and cache isn't imported? (But in that case, the user has already expressed that they want the member, not the fully-qualified name.)

Copy link
Member

Choose a reason for hiding this comment

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

yes, this:

@cache
def foo():
    ...

quck fix -> enter -> enter:

from functools import cache


@cache
def foo():
    ...

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah but in that case, the user has already written @cache.

Given:

@functools.cache
def f(x):
    return x

Then the same action yields:

import functools

@functools.cache
def f(x):
    return x

Here, we don't know which the user prefers ahead-of-time.

crates/ruff/src/cst/matchers.rs Show resolved Hide resolved
crates/ruff/src/importer.rs Show resolved Hide resolved
crates/ruff/src/importer.rs Show resolved Hide resolved
crates/ruff_python_ast/src/imports.rs Outdated Show resolved Hide resolved
@charliermarsh charliermarsh enabled auto-merge (squash) March 30, 2023 15:29
@charliermarsh charliermarsh merged commit 01357f6 into main Mar 30, 2023
12 checks passed
@charliermarsh charliermarsh deleted the charlie/require-imports branch March 30, 2023 15:33
bruxisma pushed a commit to ixm-one/pytest-cmake-presets that referenced this pull request Apr 5, 2023
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [ruff](https://togithub.com/charliermarsh/ruff) | `^0.0.260` ->
`^0.0.261` |
[![age](https://badges.renovateapi.com/packages/pypi/ruff/0.0.261/age-slim)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://badges.renovateapi.com/packages/pypi/ruff/0.0.261/adoption-slim)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://badges.renovateapi.com/packages/pypi/ruff/0.0.261/compatibility-slim/0.0.260)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://badges.renovateapi.com/packages/pypi/ruff/0.0.261/confidence-slim/0.0.260)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>charliermarsh/ruff</summary>

###
[`v0.0.261`](https://togithub.com/charliermarsh/ruff/releases/tag/v0.0.261)

[Compare
Source](https://togithub.com/charliermarsh/ruff/compare/v0.0.260...v0.0.261)

<!-- Release notes generated using configuration in .github/release.yml
at main -->

#### What's Changed

##### Rules

- \[`flake8-simplify`] Ignore `collapsible-if` violations for `if
False:` and `if True:` by
[@&#8203;JonathanPlasse](https://togithub.com/JonathanPlasse) in
[astral-sh/ruff#3732
- \[`flake8-pie`] Extend `unncessary-generator-any-all` to set
comprehensions by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#3824
- \[`flake8-simplify`] Implement `dict-get-with-none-default` (`SIM910`)
by [@&#8203;kyoto7250](https://togithub.com/kyoto7250) in
[astral-sh/ruff#3874
- \[`flake8-annotations`] Additional simple magic return types by
[@&#8203;dhruvmanila](https://togithub.com/dhruvmanila) in
[astral-sh/ruff#3805
- \[`flake8-pyi`]: fix PYI015 false positive on assignment of TypeVar &
friends by [@&#8203;bluetech](https://togithub.com/bluetech) in
[astral-sh/ruff#3861

##### Bug Fixes

- Improve robustness of argument removal for `encode` calls by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#3802
- Fix SIM222 and SIM223 false positive by
[@&#8203;JonathanPlasse](https://togithub.com/JonathanPlasse) in
[astral-sh/ruff#3832
- When checking module visibility, don't check entire ancestry by
[@&#8203;Hnasar](https://togithub.com/Hnasar) in
[astral-sh/ruff#3835
- Improve top-of-file insertions for required imports by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#3779
- Use multi-fix semantics for `inplace` removal by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#3804
- Flag non-`Name` expressions in `duplicate-isinstance-call` by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#3817
- Avoid `unnecessary-comprehension-any-all` for async generators by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#3823
- Fix `is_module_name()` and improve perf of `is_identifier()` by
[@&#8203;JonathanPlasse](https://togithub.com/JonathanPlasse) in
[astral-sh/ruff#3795
- Allow starred arguments in B030 by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#3871
- Support mutually exclusive branches for `B031` by
[@&#8203;dhruvmanila](https://togithub.com/dhruvmanila) in
[astral-sh/ruff#3844
- Consider logger candidate from `logging` module only by
[@&#8203;dhruvmanila](https://togithub.com/dhruvmanila) in
[astral-sh/ruff#3878

##### Core

- Add import insertion support to autofix capabilities by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#3787
- Generate `ImportMap` from module path to imported dependencies by
[@&#8203;chanman3388](https://togithub.com/chanman3388) in
[astral-sh/ruff#3243

##### Docs

- Add documentation for `ruff-action` (GitHub Action!) by
[@&#8203;brucearctor](https://togithub.com/brucearctor) in
[astral-sh/ruff#3857

#### New Contributors

- [@&#8203;AetherUnbound](https://togithub.com/AetherUnbound) made their
first contribution in
[astral-sh/ruff#3806
- [@&#8203;Hnasar](https://togithub.com/Hnasar) made their first
contribution in
[astral-sh/ruff#3835
- [@&#8203;nvuillam](https://togithub.com/nvuillam) made their first
contribution in
[astral-sh/ruff#3848
- [@&#8203;brucearctor](https://togithub.com/brucearctor) made their
first contribution in
[astral-sh/ruff#3857

**Full Changelog**:
astral-sh/ruff@v0.0.260...v0.0.261

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR has been generated by [Mend
Renovate](https://www.mend.io/free-developer-tools/renovate/). View
repository job log
[here](https://app.renovatebot.com/dashboard#github/ixm-one/pytest-cmake-presets).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNS4zMi4yIiwidXBkYXRlZEluVmVyIjoiMzUuMzIuMiJ9-->

Signed-off-by: Renovate Bot <bot@renovateapp.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
renovate bot added a commit to allenporter/pyrainbird that referenced this pull request Apr 7, 2023
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [ruff](https://togithub.com/charliermarsh/ruff) | `==0.0.260` ->
`==0.0.261` |
[![age](https://badges.renovateapi.com/packages/pypi/ruff/0.0.261/age-slim)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://badges.renovateapi.com/packages/pypi/ruff/0.0.261/adoption-slim)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://badges.renovateapi.com/packages/pypi/ruff/0.0.261/compatibility-slim/0.0.260)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://badges.renovateapi.com/packages/pypi/ruff/0.0.261/confidence-slim/0.0.260)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>charliermarsh/ruff</summary>

###
[`v0.0.261`](https://togithub.com/charliermarsh/ruff/releases/tag/v0.0.261)

[Compare
Source](https://togithub.com/charliermarsh/ruff/compare/v0.0.260...v0.0.261)

<!-- Release notes generated using configuration in .github/release.yml
at main -->

#### What's Changed

##### Rules

- \[`flake8-simplify`] Ignore `collapsible-if` violations for `if
False:` and `if True:` by
[@&#8203;JonathanPlasse](https://togithub.com/JonathanPlasse) in
[astral-sh/ruff#3732
- \[`flake8-pie`] Extend `unncessary-generator-any-all` to set
comprehensions by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#3824
- \[`flake8-simplify`] Implement `dict-get-with-none-default` (`SIM910`)
by [@&#8203;kyoto7250](https://togithub.com/kyoto7250) in
[astral-sh/ruff#3874
- \[`flake8-annotations`] Additional simple magic return types by
[@&#8203;dhruvmanila](https://togithub.com/dhruvmanila) in
[astral-sh/ruff#3805
- \[`flake8-pyi`]: fix PYI015 false positive on assignment of TypeVar &
friends by [@&#8203;bluetech](https://togithub.com/bluetech) in
[astral-sh/ruff#3861

##### Bug Fixes

- Improve robustness of argument removal for `encode` calls by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#3802
- Fix SIM222 and SIM223 false positive by
[@&#8203;JonathanPlasse](https://togithub.com/JonathanPlasse) in
[astral-sh/ruff#3832
- When checking module visibility, don't check entire ancestry by
[@&#8203;Hnasar](https://togithub.com/Hnasar) in
[astral-sh/ruff#3835
- Improve top-of-file insertions for required imports by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#3779
- Use multi-fix semantics for `inplace` removal by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#3804
- Flag non-`Name` expressions in `duplicate-isinstance-call` by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#3817
- Avoid `unnecessary-comprehension-any-all` for async generators by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#3823
- Fix `is_module_name()` and improve perf of `is_identifier()` by
[@&#8203;JonathanPlasse](https://togithub.com/JonathanPlasse) in
[astral-sh/ruff#3795
- Allow starred arguments in B030 by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#3871
- Support mutually exclusive branches for `B031` by
[@&#8203;dhruvmanila](https://togithub.com/dhruvmanila) in
[astral-sh/ruff#3844
- Consider logger candidate from `logging` module only by
[@&#8203;dhruvmanila](https://togithub.com/dhruvmanila) in
[astral-sh/ruff#3878

##### Core

- Add import insertion support to autofix capabilities by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#3787
- Generate `ImportMap` from module path to imported dependencies by
[@&#8203;chanman3388](https://togithub.com/chanman3388) in
[astral-sh/ruff#3243

##### Docs

- Add documentation for `ruff-action` (GitHub Action!) by
[@&#8203;brucearctor](https://togithub.com/brucearctor) in
[astral-sh/ruff#3857

#### New Contributors

- [@&#8203;AetherUnbound](https://togithub.com/AetherUnbound) made their
first contribution in
[astral-sh/ruff#3806
- [@&#8203;Hnasar](https://togithub.com/Hnasar) made their first
contribution in
[astral-sh/ruff#3835
- [@&#8203;nvuillam](https://togithub.com/nvuillam) made their first
contribution in
[astral-sh/ruff#3848
- [@&#8203;brucearctor](https://togithub.com/brucearctor) made their
first contribution in
[astral-sh/ruff#3857

**Full Changelog**:
astral-sh/ruff@v0.0.260...v0.0.261

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR has been generated by [Mend
Renovate](https://www.mend.io/free-developer-tools/renovate/). View
repository job log
[here](https://app.renovatebot.com/dashboard#github/allenporter/pyrainbird).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNS4zNC4xIiwidXBkYXRlZEluVmVyIjoiMzUuMzQuMSJ9-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
renovate bot added a commit to allenporter/flux-local that referenced this pull request Apr 7, 2023
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [ruff](https://togithub.com/charliermarsh/ruff) | `==0.0.260` ->
`==0.0.261` |
[![age](https://badges.renovateapi.com/packages/pypi/ruff/0.0.261/age-slim)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://badges.renovateapi.com/packages/pypi/ruff/0.0.261/adoption-slim)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://badges.renovateapi.com/packages/pypi/ruff/0.0.261/compatibility-slim/0.0.260)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://badges.renovateapi.com/packages/pypi/ruff/0.0.261/confidence-slim/0.0.260)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>charliermarsh/ruff</summary>

###
[`v0.0.261`](https://togithub.com/charliermarsh/ruff/releases/tag/v0.0.261)

[Compare
Source](https://togithub.com/charliermarsh/ruff/compare/v0.0.260...v0.0.261)

<!-- Release notes generated using configuration in .github/release.yml
at main -->

#### What's Changed

##### Rules

- \[`flake8-simplify`] Ignore `collapsible-if` violations for `if
False:` and `if True:` by
[@&#8203;JonathanPlasse](https://togithub.com/JonathanPlasse) in
[astral-sh/ruff#3732
- \[`flake8-pie`] Extend `unncessary-generator-any-all` to set
comprehensions by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#3824
- \[`flake8-simplify`] Implement `dict-get-with-none-default` (`SIM910`)
by [@&#8203;kyoto7250](https://togithub.com/kyoto7250) in
[astral-sh/ruff#3874
- \[`flake8-annotations`] Additional simple magic return types by
[@&#8203;dhruvmanila](https://togithub.com/dhruvmanila) in
[astral-sh/ruff#3805
- \[`flake8-pyi`]: fix PYI015 false positive on assignment of TypeVar &
friends by [@&#8203;bluetech](https://togithub.com/bluetech) in
[astral-sh/ruff#3861

##### Bug Fixes

- Improve robustness of argument removal for `encode` calls by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#3802
- Fix SIM222 and SIM223 false positive by
[@&#8203;JonathanPlasse](https://togithub.com/JonathanPlasse) in
[astral-sh/ruff#3832
- When checking module visibility, don't check entire ancestry by
[@&#8203;Hnasar](https://togithub.com/Hnasar) in
[astral-sh/ruff#3835
- Improve top-of-file insertions for required imports by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#3779
- Use multi-fix semantics for `inplace` removal by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#3804
- Flag non-`Name` expressions in `duplicate-isinstance-call` by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#3817
- Avoid `unnecessary-comprehension-any-all` for async generators by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#3823
- Fix `is_module_name()` and improve perf of `is_identifier()` by
[@&#8203;JonathanPlasse](https://togithub.com/JonathanPlasse) in
[astral-sh/ruff#3795
- Allow starred arguments in B030 by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#3871
- Support mutually exclusive branches for `B031` by
[@&#8203;dhruvmanila](https://togithub.com/dhruvmanila) in
[astral-sh/ruff#3844
- Consider logger candidate from `logging` module only by
[@&#8203;dhruvmanila](https://togithub.com/dhruvmanila) in
[astral-sh/ruff#3878

##### Core

- Add import insertion support to autofix capabilities by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#3787
- Generate `ImportMap` from module path to imported dependencies by
[@&#8203;chanman3388](https://togithub.com/chanman3388) in
[astral-sh/ruff#3243

##### Docs

- Add documentation for `ruff-action` (GitHub Action!) by
[@&#8203;brucearctor](https://togithub.com/brucearctor) in
[astral-sh/ruff#3857

#### New Contributors

- [@&#8203;AetherUnbound](https://togithub.com/AetherUnbound) made their
first contribution in
[astral-sh/ruff#3806
- [@&#8203;Hnasar](https://togithub.com/Hnasar) made their first
contribution in
[astral-sh/ruff#3835
- [@&#8203;nvuillam](https://togithub.com/nvuillam) made their first
contribution in
[astral-sh/ruff#3848
- [@&#8203;brucearctor](https://togithub.com/brucearctor) made their
first contribution in
[astral-sh/ruff#3857

**Full Changelog**:
astral-sh/ruff@v0.0.260...v0.0.261

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR has been generated by [Mend
Renovate](https://www.mend.io/free-developer-tools/renovate/). View
repository job log
[here](https://app.renovatebot.com/dashboard#github/allenporter/flux-local).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNS4zNC4xIiwidXBkYXRlZEluVmVyIjoiMzUuMzQuMSJ9-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add the possibility to add import and respect the import sorting.
4 participants