@@ -632,18 +632,47 @@ fn search_directory(
632632 let path = path. canonicalize ( ) ?;
633633 let existing_path = existing_path. join ( "componentize-py.toml" ) . canonicalize ( ) ?;
634634 if path != existing_path {
635- bail ! (
636- "multiple componentize-py.toml files found, \
637- which is not yet supported: {} and {}",
638- existing_path. display( ) ,
639- path. display( )
640- ) ;
635+ // If we find a componentize-py.toml file under a Python module which will not be used because
636+ // we already found a version of that module in an earlier `PYTHON_PATH` directory, we'll
637+ // ignore the latest one.
638+ //
639+ // For example, if the module `foo_sdk` appears twice in `PYTHON_PATH`, and both versions have
640+ // a componentize-py.toml file, we'll ignore the second one just as Python will ignore the
641+ // second module.
642+ let superseded = if let ( Ok ( relative) , Ok ( existing_relative) ) = (
643+ path. strip_prefix ( root. canonicalize ( ) ?) ,
644+ existing_path. strip_prefix ( existing_root. canonicalize ( ) ?) ,
645+ ) {
646+ matches ! (
647+ (
648+ & relative. iter( ) . collect:: <Vec <_>>( ) [ ..] ,
649+ & existing_relative. iter( ) . collect:: <Vec <_>>( ) [ ..]
650+ ) ,
651+ (
652+ [ first, _, ..] ,
653+ [ existing_first, _, ..]
654+ ) if first == existing_first
655+ )
656+ } else {
657+ false
658+ } ;
659+
660+ if superseded {
661+ false
662+ } else {
663+ bail ! (
664+ "multiple componentize-py.toml files found, \
665+ which is not yet supported: {} and {}",
666+ existing_path. display( ) ,
667+ path. display( )
668+ ) ;
669+ }
670+ } else {
671+ // When one directory in `PYTHON_PATH` is a subdirectory of the other, we consider the
672+ // subdirectory to be the true owner of the file. This is important later, when we derive a
673+ // package name by stripping the root directory from the file path.
674+ root. canonicalize ( ) ? > existing_root. canonicalize ( ) ?
641675 }
642-
643- // When one directory in `PYTHON_PATH` is a subdirectory of the other, we consider the subdirectory
644- // to be the true owner of the file. This is important later, when we derive a package name by
645- // stripping the root directory from the file path.
646- root. canonicalize ( ) ? > existing_root. canonicalize ( ) ?
647676 } else {
648677 true
649678 } ;
0 commit comments