Мне удалось реализовать вашу функцию root_relative_path, используя комбинацию модулей posixpath и pathlib.Результат -
- Независимо от платформы (если корневой путь соответствует текущей платформе)
- Путь может начинаться с
/
, ./
или ../
- И путь будет нормализован с использованием всех техник, охватываемых функцией normpath , которая включает в себя разрешение
..
s.
from pathlib import Path
import posixpath
def root_relative_path(root : str, path : str) -> str:
''' Calculates the relative path with respect to the root.
Any ".."s in the relative path will be resolved,
but not in a way that would cause the relative path to go beyond the root. '''
# posixpath.normpath doesn't work as expected if the path doesn't start with a slash, so we make sure it does
if not path.startswith('/'):
path = '/' + path
# The normalization process includes resolving any ".."s
# we're only using posixpath for the relative portion of the path, the outcome will still be platform independent
path = posixpath.normpath(path)
# Remove the beginning slash so that we're not trying to join two absolute paths
path = path[1:]
joined = Path(root) / path
# Per the OPs requirements the result needed to be a string,
# But if you're allowed to use Pathlib objects, you could just return joined without converting it to a string
return str(joined)