Skip to content

Commit

Permalink
Ensure that from-style imports are always ordered first in __future__
Browse files Browse the repository at this point in the history
  • Loading branch information
charliermarsh committed Dec 7, 2023
1 parent 9361e22 commit f76534c
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import __future__
from __future__ import annotations
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import __future__
from __future__ import annotations
4 changes: 3 additions & 1 deletion crates/ruff_linter/src/rules/isort/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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"))]
Expand Down Expand Up @@ -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(
Expand Down
32 changes: 31 additions & 1 deletion crates/ruff_linter/src/rules/isort/order.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::rules::isort::sorting::ImportStyle;
use crate::rules::isort::{ImportSection, ImportType};
use itertools::Itertools;

use super::settings::Settings;
Expand All @@ -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();
Expand Down Expand Up @@ -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))
Expand Down
Original file line number Diff line number Diff line change
@@ -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


Original file line number Diff line number Diff line change
@@ -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


0 comments on commit f76534c

Please sign in to comment.