@@ -730,20 +730,19 @@ def correct_rel_imp(imp: Union[ImportFrom, ImportAll]) -> str:
730730 return new_id
731731
732732 res : List [Tuple [int , str , int ]] = []
733+ delayed_res : List [Tuple [int , str , int ]] = []
733734 for imp in file .imports :
734735 if not imp .is_unreachable :
735736 if isinstance (imp , Import ):
736737 pri = import_priority (imp , PRI_MED )
737738 ancestor_pri = import_priority (imp , PRI_LOW )
738739 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.
747746 res .append ((pri , id , imp .line ))
748747 ancestor_parts = id .split ("." )[:- 1 ]
749748 ancestors = []
@@ -752,13 +751,15 @@ def correct_rel_imp(imp: Union[ImportFrom, ImportAll]) -> str:
752751 res .append ((ancestor_pri , "." .join (ancestors ), imp .line ))
753752 elif isinstance (imp , ImportFrom ):
754753 cur_id = correct_rel_imp (imp )
754+ any_are_submodules = False
755755 all_are_submodules = True
756756 # Also add any imported names that are submodules.
757757 pri = import_priority (imp , PRI_MED )
758758 for name , __ in imp .names :
759759 sub_id = cur_id + '.' + name
760760 if self .is_module (sub_id ):
761761 res .append ((pri , sub_id , imp .line ))
762+ any_are_submodules = True
762763 else :
763764 all_are_submodules = False
764765 # Add cur_id as a dependency, even if all of the
@@ -768,14 +769,19 @@ def correct_rel_imp(imp: Union[ImportFrom, ImportAll]) -> str:
768769 # if all of the imports are submodules, do the import at a lower
769770 # priority.
770771 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 ))
775780 elif isinstance (imp , ImportAll ):
776781 pri = import_priority (imp , PRI_HIGH )
777782 res .append ((pri , correct_rel_imp (imp ), imp .line ))
778783
784+ res .extend (delayed_res )
779785 return res
780786
781787 def is_module (self , id : str ) -> bool :
0 commit comments