mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-03 10:22:24 +00:00
Ensure that from-style imports are always ordered first in __future__
(#9039)
Closes https://github.com/astral-sh/ruff/issues/8823.
This commit is contained in:
parent
d22ce5372d
commit
946b308197
6 changed files with 70 additions and 2 deletions
2
crates/ruff_linter/resources/test/fixtures/isort/force_sort_within_sections_future.py
vendored
Normal file
2
crates/ruff_linter/resources/test/fixtures/isort/force_sort_within_sections_future.py
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
import __future__
|
||||
from __future__ import annotations
|
2
crates/ruff_linter/resources/test/fixtures/isort/future_from.py
vendored
Normal file
2
crates/ruff_linter/resources/test/fixtures/isort/future_from.py
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
import __future__
|
||||
from __future__ import annotations
|
|
@ -180,7 +180,7 @@ fn format_import_block(
|
|||
continue;
|
||||
};
|
||||
|
||||
let imports = order_imports(import_block, settings);
|
||||
let imports = order_imports(import_block, import_section, settings);
|
||||
|
||||
// Add a blank line between every section.
|
||||
if is_first_block {
|
||||
|
@ -291,6 +291,7 @@ mod tests {
|
|||
#[test_case(Path::new("force_sort_within_sections.py"))]
|
||||
#[test_case(Path::new("force_to_top.py"))]
|
||||
#[test_case(Path::new("force_wrap_aliases.py"))]
|
||||
#[test_case(Path::new("future_from.py"))]
|
||||
#[test_case(Path::new("if_elif_else.py"))]
|
||||
#[test_case(Path::new("import_from_after_import.py"))]
|
||||
#[test_case(Path::new("inline_comments.py"))]
|
||||
|
@ -701,6 +702,7 @@ mod tests {
|
|||
|
||||
#[test_case(Path::new("force_sort_within_sections.py"))]
|
||||
#[test_case(Path::new("force_sort_within_sections_with_as_names.py"))]
|
||||
#[test_case(Path::new("force_sort_within_sections_future.py"))]
|
||||
fn force_sort_within_sections(path: &Path) -> Result<()> {
|
||||
let snapshot = format!("force_sort_within_sections_{}", path.to_string_lossy());
|
||||
let mut diagnostics = test_path(
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use crate::rules::isort::sorting::ImportStyle;
|
||||
use crate::rules::isort::{ImportSection, ImportType};
|
||||
use itertools::Itertools;
|
||||
|
||||
use super::settings::Settings;
|
||||
|
@ -8,6 +9,7 @@ use super::types::{AliasData, CommentSet, ImportBlock, ImportFromStatement};
|
|||
|
||||
pub(crate) fn order_imports<'a>(
|
||||
block: ImportBlock<'a>,
|
||||
section: &ImportSection,
|
||||
settings: &Settings,
|
||||
) -> Vec<EitherImport<'a>> {
|
||||
let straight_imports = block.import.into_iter();
|
||||
|
@ -52,7 +54,35 @@ pub(crate) fn order_imports<'a>(
|
|||
},
|
||||
);
|
||||
|
||||
let ordered_imports = if settings.force_sort_within_sections {
|
||||
let ordered_imports = if matches!(section, ImportSection::Known(ImportType::Future)) {
|
||||
from_imports
|
||||
.sorted_by_cached_key(|(import_from, _, _, aliases)| {
|
||||
ModuleKey::from_module(
|
||||
import_from.module,
|
||||
None,
|
||||
import_from.level,
|
||||
aliases.first().map(|(alias, _)| (alias.name, alias.asname)),
|
||||
ImportStyle::From,
|
||||
settings,
|
||||
)
|
||||
})
|
||||
.map(ImportFrom)
|
||||
.chain(
|
||||
straight_imports
|
||||
.sorted_by_cached_key(|(alias, _)| {
|
||||
ModuleKey::from_module(
|
||||
Some(alias.name),
|
||||
alias.asname,
|
||||
None,
|
||||
None,
|
||||
ImportStyle::Straight,
|
||||
settings,
|
||||
)
|
||||
})
|
||||
.map(Import),
|
||||
)
|
||||
.collect()
|
||||
} else if settings.force_sort_within_sections {
|
||||
straight_imports
|
||||
.map(Import)
|
||||
.chain(from_imports.map(ImportFrom))
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
---
|
||||
source: crates/ruff_linter/src/rules/isort/mod.rs
|
||||
---
|
||||
force_sort_within_sections_future.py:1:1: I001 [*] Import block is un-sorted or un-formatted
|
||||
|
|
||||
1 | / import __future__
|
||||
2 | | from __future__ import annotations
|
||||
|
|
||||
= help: Organize imports
|
||||
|
||||
ℹ Safe fix
|
||||
1 |+from __future__ import annotations
|
||||
1 2 | import __future__
|
||||
2 |-from __future__ import annotations
|
||||
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
---
|
||||
source: crates/ruff_linter/src/rules/isort/mod.rs
|
||||
---
|
||||
future_from.py:1:1: I001 [*] Import block is un-sorted or un-formatted
|
||||
|
|
||||
1 | / import __future__
|
||||
2 | | from __future__ import annotations
|
||||
|
|
||||
= help: Organize imports
|
||||
|
||||
ℹ Safe fix
|
||||
1 |+from __future__ import annotations
|
||||
1 2 | import __future__
|
||||
2 |-from __future__ import annotations
|
||||
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue