Say, I have two absolute paths. I need to check if the location referring to by one of the paths is a descendant of the other. If true, I need to find out the relative path of the descendant from the ancestor. What’s a good way to implement this in Python? Any library that I can benefit from?
Share
os.path.commonprefix() and os.path.relpath() are your friends:
You can thus test whether the common prefix is one of the paths, i.e. if one of the paths is a common ancestor:
You can then find the relative paths:
You can even handle more than two paths, with this method, and test whether all the paths are all below one of them.
PS: depending on how your paths look like, you might want to perform some normalization first (this is useful in situations where one does not know whether they always end with ‘/’ or not, or if some of the paths are relative). Relevant functions include os.path.abspath() and os.path.normpath().
PPS: as Peter Briggs mentioned in the comments, the simple approach described above can fail:
even though
/usr/varis not a common prefix of the paths. Forcing all paths to end with ‘/’ before callingcommonprefix()solves this (specific) problem.PPPS: as bluenote10 mentioned, adding a slash does not solve the general problem. Here is his followup question: How to circumvent the fallacy of Python's os.path.commonprefix?
PPPPS: starting with Python 3.4, we have pathlib, a module that provides a saner path manipulation environment. I guess that the common prefix of a set of paths can be obtained by getting all the prefixes of each path (with
PurePath.parents()), taking the intersection of all these parent sets, and selecting the longest common prefix.PPPPPS: Python 3.5 introduced a proper solution to this question:
os.path.commonpath(), which returns a valid path.