From 61c0b88723d77f5f8c761917a5101f6bf3a31334 Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Mon, 27 Nov 2023 21:48:43 -0800 Subject: [PATCH] Use enum; tweak docs --- crates/ruff_linter/src/rules/isort/order.rs | 16 ++++-- crates/ruff_linter/src/rules/isort/sorting.rs | 14 ++++-- crates/ruff_workspace/src/options.rs | 49 +++++++++++-------- ruff.schema.json | 4 +- 4 files changed, 54 insertions(+), 29 deletions(-) diff --git a/crates/ruff_linter/src/rules/isort/order.rs b/crates/ruff_linter/src/rules/isort/order.rs index 01f8362a7ffec..25430b84ad6f9 100644 --- a/crates/ruff_linter/src/rules/isort/order.rs +++ b/crates/ruff_linter/src/rules/isort/order.rs @@ -1,3 +1,4 @@ +use crate::rules::isort::sorting::ImportStyle; use itertools::Itertools; use super::settings::Settings; @@ -61,22 +62,29 @@ pub(crate) fn order_imports<'a>( alias.asname, None, None, + ImportStyle::Straight, settings, - true, ), ImportFrom((import_from, _, _, aliases)) => ModuleKey::from_module( import_from.module, None, import_from.level, aliases.first().map(|(alias, _)| (alias.name, alias.asname)), + ImportStyle::From, settings, - false, ), }) .collect() } else { let ordered_straight_imports = straight_imports.sorted_by_cached_key(|(alias, _)| { - ModuleKey::from_module(Some(alias.name), alias.asname, None, None, settings, true) + ModuleKey::from_module( + Some(alias.name), + alias.asname, + None, + None, + ImportStyle::Straight, + settings, + ) }); let ordered_from_imports = from_imports.sorted_by_cached_key(|(import_from, _, _, aliases)| { @@ -85,8 +93,8 @@ pub(crate) fn order_imports<'a>( None, import_from.level, aliases.first().map(|(alias, _)| (alias.name, alias.asname)), + ImportStyle::From, settings, - false, ) }); if settings.from_first { diff --git a/crates/ruff_linter/src/rules/isort/sorting.rs b/crates/ruff_linter/src/rules/isort/sorting.rs index 97d65938127d7..aa979fc90c89e 100644 --- a/crates/ruff_linter/src/rules/isort/sorting.rs +++ b/crates/ruff_linter/src/rules/isort/sorting.rs @@ -65,12 +65,20 @@ impl<'a> From for NatOrdStr<'a> { } } -#[derive(Debug, PartialOrd, Ord, PartialEq, Eq)] +#[derive(Debug, Copy, Clone, PartialOrd, Ord, PartialEq, Eq)] pub(crate) enum Distance { Nearest(u32), Furthest(Reverse), } +#[derive(Debug, Copy, Clone, PartialOrd, Ord, PartialEq, Eq)] +pub(crate) enum ImportStyle { + // Ex) `import foo` + Straight, + // Ex) `from foo import bar` + From, +} + /// A comparable key to capture the desired sorting order for an imported module (e.g., /// `foo` in `from foo import bar`). #[derive(Debug, PartialOrd, Ord, PartialEq, Eq)] @@ -90,8 +98,8 @@ impl<'a> ModuleKey<'a> { asname: Option<&'a str>, level: Option, first_alias: Option<(&'a str, Option<&'a str>)>, + style: ImportStyle, settings: &Settings, - straight_import: bool, ) -> Self { let level = level.unwrap_or_default(); @@ -100,7 +108,7 @@ impl<'a> ModuleKey<'a> { .unwrap_or_default(); // `false` < `true` so we get forced to top first let maybe_length = (settings.length_sort - || (settings.length_sort_straight && straight_import)) + || (settings.length_sort_straight && style == ImportStyle::Straight)) .then_some(name.map(str::width).unwrap_or_default() + level as usize); let distance = match settings.relative_imports_order { diff --git a/crates/ruff_workspace/src/options.rs b/crates/ruff_workspace/src/options.rs index e9afcd9389336..05f4522710cd9 100644 --- a/crates/ruff_workspace/src/options.rs +++ b/crates/ruff_workspace/src/options.rs @@ -2047,24 +2047,20 @@ pub struct IsortOptions { )] pub from_first: Option, - // Tables are required to go last. - /// A list of mappings from section names to modules. - /// By default custom sections are output last, but this can be overridden with `section-order`. - #[option( - default = "{}", - value_type = "dict[str, list[str]]", - scope = "sections", - example = r#" - # Group all Django imports into a separate section. - "django" = ["django"] - "# - )] - pub sections: Option>>, - - /// Sort imports by their string length. + /// Sort imports by their string length, such that shorter imports appear + /// before longer imports. For example, by default, imports will be sorted + /// alphabetically, as in: + /// ```python + /// import collections + /// import os + /// ``` /// - /// The string length is computed using the [`unicode_width`](https://crates.io/crates/unicode-width) crate, - /// i.e. it is the displayed width of the string according to [Unicode Standard Annex #11 rules](http://www.unicode.org/reports/tr11/). + /// Setting `length-sort = true` will instead sort such that shorter imports + /// appear before longer imports, as in: + /// ```python + /// import os + /// import collections + /// ``` #[option( default = r#"false"#, value_type = "bool", @@ -2074,9 +2070,8 @@ pub struct IsortOptions { )] pub length_sort: Option, - /// Sort straight imports by their string length. - /// - /// Same as `length-sort` but does not affect from imports. + /// Sort straight imports by their string length. Similar to `length-sort`, + /// but applies only to straight imports and doesn't affect `from` imports. #[option( default = r#"false"#, value_type = "bool", @@ -2085,6 +2080,20 @@ pub struct IsortOptions { "# )] pub length_sort_straight: Option, + + // Tables are required to go last. + /// A list of mappings from section names to modules. + /// By default custom sections are output last, but this can be overridden with `section-order`. + #[option( + default = "{}", + value_type = "dict[str, list[str]]", + scope = "sections", + example = r#" + # Group all Django imports into a separate section. + "django" = ["django"] + "# + )] + pub sections: Option>>, } impl IsortOptions { diff --git a/ruff.schema.json b/ruff.schema.json index 11dc89e015b30..d5e7f0c0acc31 100644 --- a/ruff.schema.json +++ b/ruff.schema.json @@ -1478,14 +1478,14 @@ } }, "length-sort": { - "description": "Sort imports by their string length.\n\nThe string length is computed using the [`unicode_width`](https://crates.io/crates/unicode-width) crate, i.e. it is the displayed width of the string according to [Unicode Standard Annex #11 rules](http://www.unicode.org/reports/tr11/).", + "description": "Sort imports by their string length, such that shorter imports appear before longer imports. For example, by default, imports will be sorted alphabetically, as in: ```python import collections import os ```\n\nSetting `length-sort = true` will instead sort such that shorter imports appear before longer imports, as in: ```python import os import collections ```", "type": [ "boolean", "null" ] }, "length-sort-straight": { - "description": "Sort straight imports by their string length.\n\nSame as `length-sort` but does not affect from imports.", + "description": "Sort straight imports by their string length. Similar to `length-sort`, but applies only to straight imports and doesn't affect `from` imports.", "type": [ "boolean", "null"