@@ -730,20 +730,19 @@ def correct_rel_imp(imp: Union[ImportFrom, ImportAll]) -> str:
730
730
return new_id
731
731
732
732
res : List [Tuple [int , str , int ]] = []
733
+ delayed_res : List [Tuple [int , str , int ]] = []
733
734
for imp in file .imports :
734
735
if not imp .is_unreachable :
735
736
if isinstance (imp , Import ):
736
737
pri = import_priority (imp , PRI_MED )
737
738
ancestor_pri = import_priority (imp , PRI_LOW )
738
739
for id , _ in imp .ids :
739
- # We append the target (e.g. foo.bar.baz)
740
- # before the ancestors (e.g. foo and foo.bar)
741
- # so that, if FindModuleCache finds the target
742
- # module in a package marked with py.typed
743
- # underneath a namespace package installed in
744
- # site-packages, (gasp), that cache's
745
- # knowledge of the ancestors can be primed
746
- # when it is asked to find the target.
740
+ # We append the target (e.g. foo.bar.baz) before the ancestors (e.g. foo
741
+ # and foo.bar) so that, if FindModuleCache finds the target module in a
742
+ # package marked with py.typed underneath a namespace package installed in
743
+ # site-packages, (gasp), that cache's knowledge of the ancestors
744
+ # (aka FindModuleCache.ns_ancestors) can be primed when it is asked to find
745
+ # the parent.
747
746
res .append ((pri , id , imp .line ))
748
747
ancestor_parts = id .split ("." )[:- 1 ]
749
748
ancestors = []
@@ -752,13 +751,15 @@ def correct_rel_imp(imp: Union[ImportFrom, ImportAll]) -> str:
752
751
res .append ((ancestor_pri , "." .join (ancestors ), imp .line ))
753
752
elif isinstance (imp , ImportFrom ):
754
753
cur_id = correct_rel_imp (imp )
754
+ any_are_submodules = False
755
755
all_are_submodules = True
756
756
# Also add any imported names that are submodules.
757
757
pri = import_priority (imp , PRI_MED )
758
758
for name , __ in imp .names :
759
759
sub_id = cur_id + '.' + name
760
760
if self .is_module (sub_id ):
761
761
res .append ((pri , sub_id , imp .line ))
762
+ any_are_submodules = True
762
763
else :
763
764
all_are_submodules = False
764
765
# Add cur_id as a dependency, even if all of the
@@ -768,14 +769,19 @@ def correct_rel_imp(imp: Union[ImportFrom, ImportAll]) -> str:
768
769
# if all of the imports are submodules, do the import at a lower
769
770
# priority.
770
771
pri = import_priority (imp , PRI_HIGH if not all_are_submodules else PRI_LOW )
771
- # The imported module goes in after the
772
- # submodules, for the same namespace related
773
- # reasons discussed in the Import case.
774
- res .append ((pri , cur_id , imp .line ))
772
+ # The imported module goes in after the submodules, for the same namespace
773
+ # related reasons discussed in the Import case.
774
+ # There is an additional twist: if none of the submodules exist,
775
+ # we delay the import in case other imports of other submodules succeed.
776
+ if any_are_submodules :
777
+ res .append ((pri , cur_id , imp .line ))
778
+ else :
779
+ delayed_res .append ((pri , cur_id , imp .line ))
775
780
elif isinstance (imp , ImportAll ):
776
781
pri = import_priority (imp , PRI_HIGH )
777
782
res .append ((pri , correct_rel_imp (imp ), imp .line ))
778
783
784
+ res .extend (delayed_res )
779
785
return res
780
786
781
787
def is_module (self , id : str ) -> bool :
0 commit comments