@@ -12,6 +12,7 @@ use normalize::normalize_imports;
12
12
use order:: order_imports;
13
13
use settings:: RelativeImportsOrder ;
14
14
use sorting:: cmp_either_import;
15
+ use strum:: IntoEnumIterator ;
15
16
use track:: { Block , Trailer } ;
16
17
use types:: EitherImport :: { Import , ImportFrom } ;
17
18
use types:: { AliasData , CommentSet , EitherImport , OrderedImportBlock , TrailingComma } ;
@@ -232,7 +233,7 @@ fn format_import_block(
232
233
target_version : PythonVersion ,
233
234
) -> String {
234
235
// Categorize by type (e.g., first-party vs. third-party).
235
- let block_by_type = categorize_imports (
236
+ let mut block_by_type = categorize_imports (
236
237
block,
237
238
src,
238
239
package,
@@ -247,7 +248,17 @@ fn format_import_block(
247
248
248
249
// Generate replacement source code.
249
250
let mut is_first_block = true ;
250
- for ( import_type, import_block) in block_by_type {
251
+ let mut pending_lines_before = false ;
252
+ for import_type in ImportType :: iter ( ) {
253
+ let import_block = block_by_type. remove ( & import_type) ;
254
+
255
+ if !no_lines_before. contains ( & import_type) {
256
+ pending_lines_before = true ;
257
+ }
258
+ let Some ( import_block) = import_block else {
259
+ continue ;
260
+ } ;
261
+
251
262
let mut imports = order_imports (
252
263
import_block,
253
264
order_by_type,
@@ -280,8 +291,10 @@ fn format_import_block(
280
291
// Add a blank line between every section.
281
292
if is_first_block {
282
293
is_first_block = false ;
283
- } else if !no_lines_before. contains ( & import_type) {
294
+ pending_lines_before = false ;
295
+ } else if pending_lines_before {
284
296
output. push_str ( stylist. line_ending ( ) ) ;
297
+ pending_lines_before = false ;
285
298
}
286
299
287
300
let mut lines_inserted = false ;
@@ -791,6 +804,31 @@ mod tests {
791
804
Ok ( ( ) )
792
805
}
793
806
807
+ #[ test_case( Path :: new( "no_lines_before_with_empty_sections.py" ) ) ]
808
+ fn no_lines_before_with_empty_sections ( path : & Path ) -> Result < ( ) > {
809
+ let snapshot = format ! (
810
+ "no_lines_before_with_empty_sections.py_{}" ,
811
+ path. to_string_lossy( )
812
+ ) ;
813
+ let mut diagnostics = test_path (
814
+ Path :: new ( "isort" ) . join ( path) . as_path ( ) ,
815
+ & Settings {
816
+ isort : super :: settings:: Settings {
817
+ no_lines_before : BTreeSet :: from ( [
818
+ ImportType :: StandardLibrary ,
819
+ ImportType :: LocalFolder ,
820
+ ] ) ,
821
+ ..super :: settings:: Settings :: default ( )
822
+ } ,
823
+ src : vec ! [ test_resource_path( "fixtures/isort" ) ] ,
824
+ ..Settings :: for_rule ( Rule :: UnsortedImports )
825
+ } ,
826
+ ) ?;
827
+ diagnostics. sort_by_key ( |diagnostic| diagnostic. location ) ;
828
+ assert_yaml_snapshot ! ( snapshot, diagnostics) ;
829
+ Ok ( ( ) )
830
+ }
831
+
794
832
#[ test_case( Path :: new( "lines_after_imports_nothing_after.py" ) ) ]
795
833
#[ test_case( Path :: new( "lines_after_imports_func_after.py" ) ) ]
796
834
#[ test_case( Path :: new( "lines_after_imports_class_after.py" ) ) ]
0 commit comments