mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-29 13:25:17 +00:00
![]() Resolves #10390 and starts to address #10391 # Changes to behavior * In `__init__.py` we now offer some fixes for unused imports. * If the import binding is first-party this PR suggests a fix to turn it into a redundant alias. * If the import binding is not first-party, this PR suggests a fix to remove it from the `__init__.py`. * The fix-titles are specific to these new suggested fixes. * `checker.settings.ignore_init_module_imports` setting is deprecated/ignored. There is probably a documentation change to make that complete which I haven't done. --- <details><summary>Old description of implementation changes</summary> # Changes to the implementation * In the body of the loop over import statements that contain unused bindings, the bindings are partitioned into `to_reexport` and `to_remove` (according to how we want to resolve the fact they're unused) with the following predicate: ```rust in_init && is_first_party(checker, &import.qualified_name().to_string()) // true means make it a reexport ``` * Instead of generating a single fix per import statement, we now generate up to two fixes per import statement: ```rust (fix_by_removing_imports(checker, node_id, &to_remove, in_init).ok(), fix_by_reexporting(checker, node_id, &to_reexport, dunder_all).ok()) ``` * The `to_remove` fixes are unsafe when `in_init`. * The `to_explicit` fixes are safe. Currently, until a future PR, we make them redundant aliases (e.g. `import a` would become `import a as a`). ## Other changes * `checker.settings.ignore_init_module_imports` is deprecated/ignored. Instead, all fixes are gated on `checker.settings.preview.is_enabled()`. * Got rid of the pattern match on the import-binding bound by the inner loop because it seemed less readable than referencing fields on the binding. * [x] `// FIXME: rename "imports" to "bindings"` if reviewer agrees (see code) * [x] `// FIXME: rename "node_id" to "import_statement"` if reviewer agrees (see code) <details> <summary><h2>Scope cut until a future PR</h2></summary> * (Not implemented) The `to_explicit` fixes will be added to `__all__` unless it doesn't exist. When `__all__` doesn't exist they're resolved by converting to redundant aliases (e.g. `import a` would become `import a as a`). --- </details> # Test plan * [x] `crates/ruff_linter/resources/test/fixtures/pyflakes/F401_24` contains an `__init__.py` with*out* `__all__` that exercises the features in this PR, but it doesn't pass. * [x] `crates/ruff_linter/resources/test/fixtures/pyflakes/F401_25_dunder_all` contains an `__init__.py` *with* `__all__` that exercises the features in this PR, but it doesn't pass. * [x] Write unit tests for the new edit functions in `fix::edits::make_redundant_alias`. </details> --------- Co-authored-by: Micha Reiser <micha@reiser.io> |
||
---|---|---|
.. | ||
resources | ||
src | ||
__init__.py | ||
Cargo.toml |