mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-28 04:45:01 +00:00
Implement isort's default-section
setting (#10149)
## Summary
This fixes https://github.com/astral-sh/ruff/issues/7868.
Support isort's `default-section` feature which allows any imports that
match sections that are not in `section-order` to be mapped to a
specifically named section.
https://pycqa.github.io/isort/docs/configuration/options.html#default-section
This has a few implications:
- It is no longer required that all known sections are defined in
`section-order`.
- This is technically a bw-incompat change because currently if folks
define custom groups, and do not define a `section-order`, the code used
to add all known sections to `section-order` while emitting warnings.
**However, when this happened, users would be seeing warnings so I do
not think it should count as a bw-incompat change.**
## Test Plan
- Added a new test.
- Did not break any existing tests.
Finally, I ran the following config against Pyramid's complex codebase
that was previously using isort and this change worked there.
### pyramid's previous isort config
5f7e286b06/pyproject.toml (L22-L37)
```toml
[tool.isort]
profile = "black"
multi_line_output = 3
src_paths = ["src", "tests"]
skip_glob = ["docs/*"]
include_trailing_comma = true
force_grid_wrap = false
combine_as_imports = true
line_length = 79
force_sort_within_sections = true
no_lines_before = "THIRDPARTY"
sections = "FUTURE,THIRDPARTY,FIRSTPARTY,LOCALFOLDER"
default_section = "THIRDPARTY"
known_first_party = "pyramid"
```
### tested with ruff isort config
```toml
[tool.ruff.lint.isort]
case-sensitive = true
combine-as-imports = true
force-sort-within-sections = true
section-order = [
"future",
"third-party",
"first-party",
"local-folder",
]
default-section = "third-party"
known-first-party = [
"pyramid",
]
```
This commit is contained in:
parent
8e0a70cfa3
commit
c9931a548f
11 changed files with 174 additions and 23 deletions
|
@ -2099,6 +2099,16 @@ pub struct IsortOptions {
|
|||
)]
|
||||
pub section_order: Option<Vec<ImportSection>>,
|
||||
|
||||
/// Define a default section for any imports that don't fit into the specified `section-order`.
|
||||
#[option(
|
||||
default = r#"third-party"#,
|
||||
value_type = "str",
|
||||
example = r#"
|
||||
default-section = "third-party"
|
||||
"#
|
||||
)]
|
||||
pub default_section: Option<ImportSection>,
|
||||
|
||||
/// Put all imports into the same section bucket.
|
||||
///
|
||||
/// For example, rather than separating standard library and third-party imports, as in:
|
||||
|
@ -2226,6 +2236,9 @@ impl IsortOptions {
|
|||
if no_sections && self.section_order.is_some() {
|
||||
warn_user_once!("`section-order` is ignored when `no-sections` is set to `true`");
|
||||
}
|
||||
if no_sections && self.default_section.is_some() {
|
||||
warn_user_once!("`default-section` is ignored when `no-sections` is set to `true`");
|
||||
}
|
||||
if no_sections && self.sections.is_some() {
|
||||
warn_user_once!("`sections` is ignored when `no-sections` is set to `true`");
|
||||
}
|
||||
|
@ -2241,6 +2254,10 @@ impl IsortOptions {
|
|||
let mut section_order: Vec<_> = self
|
||||
.section_order
|
||||
.unwrap_or_else(|| ImportType::iter().map(ImportSection::Known).collect());
|
||||
let default_section = self
|
||||
.default_section
|
||||
.unwrap_or(ImportSection::Known(ImportType::ThirdParty));
|
||||
|
||||
let known_first_party = self
|
||||
.known_first_party
|
||||
.map(|names| {
|
||||
|
@ -2344,24 +2361,13 @@ impl IsortOptions {
|
|||
}
|
||||
}
|
||||
|
||||
// Add all built-in sections to `section_order`, if not already present.
|
||||
for section in ImportType::iter().map(ImportSection::Known) {
|
||||
if !section_order.contains(§ion) {
|
||||
warn_user_once!(
|
||||
"`section-order` is missing built-in section: `{:?}`",
|
||||
section
|
||||
);
|
||||
section_order.push(section);
|
||||
}
|
||||
}
|
||||
|
||||
// Add all user-defined sections to `section-order`, if not already present.
|
||||
for section_name in sections.keys() {
|
||||
let section = ImportSection::UserDefined(section_name.clone());
|
||||
if !section_order.contains(§ion) {
|
||||
warn_user_once!("`section-order` is missing section: `{:?}`", section);
|
||||
section_order.push(section);
|
||||
}
|
||||
// Verify that `default_section` is in `section_order`.
|
||||
if !section_order.contains(&default_section) {
|
||||
warn_user_once!(
|
||||
"`section-order` must contain `default-section`: {:?}",
|
||||
default_section,
|
||||
);
|
||||
section_order.push(default_section.clone());
|
||||
}
|
||||
|
||||
Ok(isort::settings::Settings {
|
||||
|
@ -2394,6 +2400,7 @@ impl IsortOptions {
|
|||
lines_between_types,
|
||||
forced_separate: Vec::from_iter(self.forced_separate.unwrap_or_default()),
|
||||
section_order,
|
||||
default_section,
|
||||
no_sections,
|
||||
from_first,
|
||||
length_sort: self.length_sort.unwrap_or(false),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue