diff --git a/resources/test/fixtures/isort/comments.py b/resources/test/fixtures/isort/comments.py index 8078542f4a..e3f0460699 100644 --- a/resources/test/fixtures/isort/comments.py +++ b/resources/test/fixtures/isort/comments.py @@ -23,3 +23,6 @@ from A import ( b, # Comment 10 c, # Comment 11 ) + +from D import a_long_name_to_force_multiple_lines # Comment 12 +from D import another_long_name_to_force_multiple_lines # Comment 13 diff --git a/src/isort/mod.rs b/src/isort/mod.rs index b1c7d96f11..0639e1abbc 100644 --- a/src/isort/mod.rs +++ b/src/isort/mod.rs @@ -191,33 +191,25 @@ fn normalize_imports(imports: Vec, combine_as_imports: bool) -> atop, inline, } => { - // Associate the comments with the first alias (best effort). + let single_import = names.len() == 1; + + // If we're dealing with a multi-import block (i.e., a non-star, non-aliased + // import), associate the comments with the first alias (best + // effort). if let Some(alias) = names.first() { - if alias.name == "*" { - let entry = block + let entry = if alias.name == "*" { + block .import_from_star .entry(ImportFromData { module, level }) - .or_default(); - for comment in atop { - entry.atop.push(comment.value); - } - for comment in inline { - entry.inline.push(comment.value); - } + .or_default() } else if alias.asname.is_none() || combine_as_imports { - let entry = &mut block + &mut block .import_from .entry(ImportFromData { module, level }) .or_default() - .0; - for comment in atop { - entry.atop.push(comment.value); - } - for comment in inline { - entry.inline.push(comment.value); - } + .0 } else { - let entry = block + block .import_from_as .entry(( ImportFromData { module, level }, @@ -226,30 +218,19 @@ fn normalize_imports(imports: Vec, combine_as_imports: bool) -> asname: alias.asname, }, )) - .or_default(); - for comment in atop { - entry.atop.push(comment.value); - } - for comment in inline { - entry.inline.push(comment.value); - } - } - } + .or_default() + }; - // Create an entry for every alias. - for alias in names { - if alias.name == "*" { - let entry = block - .import_from_star - .entry(ImportFromData { module, level }) - .or_default(); - for comment in alias.atop { - entry.atop.push(comment.value); - } - for comment in alias.inline { - entry.inline.push(comment.value); - } - } else if alias.asname.is_none() || combine_as_imports { + for comment in atop { + entry.atop.push(comment.value); + } + + // Associate inline comments with first alias if multiple names have been + // imported, i.e., the comment applies to all names; otherwise, associate + // with the alias. + if single_import + && (alias.name != "*" && (alias.asname.is_none() || combine_as_imports)) + { let entry = block .import_from .entry(ImportFromData { module, level }) @@ -260,14 +241,36 @@ fn normalize_imports(imports: Vec, combine_as_imports: bool) -> asname: alias.asname, }) .or_default(); - for comment in alias.atop { - entry.atop.push(comment.value); - } - for comment in alias.inline { + for comment in inline { entry.inline.push(comment.value); } } else { - let entry = block + for comment in inline { + entry.inline.push(comment.value); + } + } + } + + // Create an entry for every alias. + for alias in names { + let entry = if alias.name == "*" { + block + .import_from_star + .entry(ImportFromData { module, level }) + .or_default() + } else if alias.asname.is_none() || combine_as_imports { + block + .import_from + .entry(ImportFromData { module, level }) + .or_default() + .1 + .entry(AliasData { + name: alias.name, + asname: alias.asname, + }) + .or_default() + } else { + block .import_from_as .entry(( ImportFromData { module, level }, @@ -276,13 +279,14 @@ fn normalize_imports(imports: Vec, combine_as_imports: bool) -> asname: alias.asname, }, )) - .or_default(); - entry - .atop - .extend(alias.atop.into_iter().map(|comment| comment.value)); - for comment in alias.inline { - entry.inline.push(comment.value); - } + .or_default() + }; + + for comment in alias.atop { + entry.atop.push(comment.value); + } + for comment in alias.inline { + entry.inline.push(comment.value); } } } diff --git a/src/isort/snapshots/ruff__isort__tests__comments.py.snap b/src/isort/snapshots/ruff__isort__tests__comments.py.snap index 44bddcda4f..de6712212a 100644 --- a/src/isort/snapshots/ruff__isort__tests__comments.py.snap +++ b/src/isort/snapshots/ruff__isort__tests__comments.py.snap @@ -7,14 +7,14 @@ expression: checks row: 3 column: 0 end_location: - row: 26 + row: 29 column: 0 fix: - content: "import B # Comment 4\n\n# Comment 3a\n# Comment 3b\nimport C\nimport D\n\n# Comment 5\n# Comment 6\nfrom A import (\n a, # Comment 7 # Comment 9\n b, # Comment 10\n c, # Comment 8 # Comment 11\n)\n" + content: "import B # Comment 4\n\n# Comment 3a\n# Comment 3b\nimport C\nimport D\n\n# Comment 5\n# Comment 6\nfrom A import (\n a, # Comment 7 # Comment 9\n b, # Comment 10\n c, # Comment 8 # Comment 11\n)\nfrom D import (\n a_long_name_to_force_multiple_lines, # Comment 12\n another_long_name_to_force_multiple_lines, # Comment 13\n)\n" location: row: 3 column: 0 end_location: - row: 26 + row: 29 column: 0 diff --git a/src/isort/snapshots/ruff__isort__tests__fit_line_length_comment.py.snap b/src/isort/snapshots/ruff__isort__tests__fit_line_length_comment.py.snap index 80d84c662f..97ed667ecf 100644 --- a/src/isort/snapshots/ruff__isort__tests__fit_line_length_comment.py.snap +++ b/src/isort/snapshots/ruff__isort__tests__fit_line_length_comment.py.snap @@ -10,7 +10,7 @@ expression: checks row: 5 column: 0 fix: - content: "import a\n\n# Don't take this comment into account when determining whether the next import can fit on one line.\nfrom b import c\nfrom d import ( # Do take this comment into account when determining whether the next import can fit on one line.\n e,\n)\n" + content: "import a\n\n# Don't take this comment into account when determining whether the next import can fit on one line.\nfrom b import c\nfrom d import (\n e, # Do take this comment into account when determining whether the next import can fit on one line.\n)\n" location: row: 1 column: 0