I would like to find the relative path between two absolute paths. I have existing code that is generally using pathlib.Path
for interacting with the filesystem, but I've run into a problem that seems easy to solve with os.path.relpath
but (so far) intractable with pathlib.Path
.
I have:
/home/project/cluster-scope/base/namespaces/acm
../../../components/monitoring-rbac
/home/project/cluster-scope/base/core/namespaces/acm
I want to compute a new relative path to (B) from (C). This works:
>>> import os
>>> path_A = '/home/project/cluster-scope/base/namespaces/acm'
>>> path_B = '../../../components/monitoring-rbac'
>>> path_C = '/home/project/cluster-scope/base/core/namespaces/acm'
>>> path_B_abs = os.path.abspath(os.path.join(path_A, path_B))
>>> os.path.relpath(path_B_abs, path_C)
'../../../../components/monitoring-rbac'
But this does not:
>>> from pathlib import Path
>>> path_A = Path('/home/project/cluster-scope/base/namespaces/acm')
>>> path_B = Path('../../../components/monitoring-rbac')
>>> path_C = Path('/home/project/cluster-scope/base/core/namespaces/acm')
>>> path_B_abs = (path_A / path_B).resolve()
>>> path_B_abs.relative_to(path_C)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib64/python3.9/pathlib.py", line 928, in relative_to
raise ValueError("{!r} is not in the subpath of {!r}"
ValueError: '/home/project/cluster-scope/components/monitoring-rbac' is not in the subpath of '/home/project/cluster-scope/base/core/namespaces/acm' OR one path is relative and the other is absolute.
The message in that ValueError
exception seems inaccurate, or at
least misleading: the two paths obviously share a common parent. Is
there any way to compute the new relative path using the
pathlib.Path
? I realize I can just use os.path.relpath
and be done with it, but I'm curious if I'm misunderstanding the use of pathlib
's relative_to
method.
In this article, I have introduced another Python built-in library, the Pathlib. It is considered to be more advanced, convenient and provides more stunning features than the OS library. Of course, we still need to know how to use the OS library as it is one of the most powerful and basic libraries in Python.
Pathlib allows you to easily iterate over that directory's content and also get files and folders that match a specific pattern. Remember the glob module that you used to import along with the os module to get paths that match a pattern?
The pathlib module replaces many of these filesystem-related os utilities with methods on the Path object. Notice that the pathlib code puts the path first because of method chaining!
The pathlib is a Python module which provides an object API for working with files and directories. The pathlib is a standard module. Path is the core object to work with files.
Apparently this is not possible. According to an issue:
I agree it's worth improving the error message (and probably the docs too).
It's never made clear that relative_to only looks deeper (won't ever generate leading ".." parts) - the closest hint in the docs is that os.path.relpath is different (and that isn't even in the relative_to() section).
In the current version the docstring says
"""Return the relative path to another path identified by the passed
arguments. If the operation is not possible (because this is not
a subpath of the other path), raise ValueError.
"""
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With