python-3.xpath

How to force absolute path to be relative when joining?


What is the idiomatic way to turn an absolute path into a relative path when joining?

Inputs:

abs = r"\\server\share\data"
newroot = r"X:\project"

Desired result:

X:\project\server\share\data

Both os.path.join() and pathlib.Path().joinpath() trim everything after the drive letter:

>>> os.path.join(newroot, abs)
'\\\\server\\share\\data'

>>> pathlib.Path(newroot).joinpath(abs)
WindowsPath('//server/share/data')

I can make them work by stripping the leading slashes:

>>> os.path.join(newroot, abs[2:])
'X:\\project\\server\\share\\data'

but that means I need to wrap in a test to find out whether the incoming path is actually absolute and to count how many slashes to remove. This just feels like a place for me to create bugs.

Note: Windows syntax is shown but I imagine the problem is cross platform and best-practice answer is probably that way also.


Solution

  • PurePath.relative_to seems to do the job:

    >>> Path("/mnt") / (Path("/some/where").relative_to("/"))
    PosixPath('/mnt/some/where')