@@ -60,23 +60,32 @@ def find_parents(root, path, names):
6060 """Find files matching the given names relative to the given path.
6161
6262 Args:
63- path (str): The path to start searching up from
64- names (List[str]): The file/directory names to look for
63+ path (str): The file path to start searching up from.
64+ names (List[str]): The file/directory names to look for.
6565 root (str): The directory at which to stop recursing upwards.
6666
6767 Note:
6868 The path MUST be within the root.
6969 """
7070 if not root :
7171 return []
72+
7273 if not os .path .commonprefix ((root , path )):
7374 log .warning ("Path %s not in %s" , path , root )
7475 return []
7576
76- curdir = os .path .dirname (path )
77+ # Split the relative by directory, generate all the parent directories, then check each of them.
78+ # This avoids running a loop that has different base-cases for unix/windows
79+ # e.g. /a/b and /a/b/c/d/e.py -> ['/a/b', 'c', 'd']
80+ dirs = [root ] + os .path .relpath (os .path .dirname (path ), root ).split (os .path .sep )
7781
78- while curdir != os .path .dirname (root ) and curdir != '/' :
79- existing = list (filter (os .path .exists , [os .path .join (curdir , n ) for n in names ]))
82+ # Search each of /a/b/c, /a/b, /a
83+ while dirs :
84+ search_dir = os .path .join (* dirs )
85+ existing = list (filter (os .path .exists , [os .path .join (search_dir , n ) for n in names ]))
8086 if existing :
8187 return existing
82- curdir = os .path .dirname (curdir )
88+ dirs .pop ()
89+
90+ # Otherwise nothing
91+ return []
0 commit comments