@@ -60,23 +60,32 @@ def find_parents(root, path, names):
60
60
"""Find files matching the given names relative to the given path.
61
61
62
62
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.
65
65
root (str): The directory at which to stop recursing upwards.
66
66
67
67
Note:
68
68
The path MUST be within the root.
69
69
"""
70
70
if not root :
71
71
return []
72
+
72
73
if not os .path .commonprefix ((root , path )):
73
74
log .warning ("Path %s not in %s" , path , root )
74
75
return []
75
76
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 )
77
81
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 ]))
80
86
if existing :
81
87
return existing
82
- curdir = os .path .dirname (curdir )
88
+ dirs .pop ()
89
+
90
+ # Otherwise nothing
91
+ return []
0 commit comments