0

I'm facing an issue while trying to get relative path to a parent level directory using pathlib but os.path works. How to satisfy the requirement using pathlib APIs?

In [1]: import os

In [2]: p1 = "/a/b/c"

In [3]: p2 = "/a/b/c/d/e"

In [4]: os.path.relpath(p1, p2)
Out[4]: '../..'

But below code throws exception -

In [5]: import pathlib

In [6]: c = pathlib.Path(p1).relative_to(pathlib.Path(p2))
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[6], line 1
----> 1 c = pathlib.Path(p1).relative_to(pathlib.Path(p2))

File ~/.conda/envs/slm-scratch-experiment/lib/python3.9/pathlib.py:939, in PurePath.relative_to(self, *other)
    937 if (root or drv) if n == 0 else cf(abs_parts[:n]) != cf(to_abs_parts):
    938     formatted = self._format_parsed_parts(to_drv, to_root, to_parts)
--> 939     raise ValueError("{!r} is not in the subpath of {!r}"
    940             " OR one path is relative and the other is absolute."
    941                      .format(str(self), str(formatted)))
    942 return self._from_parsed_parts('', root if n == 1 else '',
    943                                abs_parts[n:])

ValueError: '/a/b/c' is not in the subpath of '/a/b/c/d/e' OR one path is relative and the other is absolute.
soumeng78
  • 600
  • 7
  • 12
  • 2
    The path passed to `relative_to` should be the parent path - `c = pathlib.Path(p2).relative_to(pathlib.Path(p1))` – Iain Shelvington Feb 03 '23 at 22:04
  • 1
    Flip your paths – Shmack Feb 03 '23 at 22:04
  • @Shmack - if I flip, it won't give correct result. In [7]: c = pathlib.Path(p2).relative_to(pathlib.Path(p1)) In [8]: c Out[8]: PosixPath('d/e') – soumeng78 Feb 03 '23 at 22:35
  • @IainShelvington - please refer my previous comment. – soumeng78 Feb 03 '23 at 22:36
  • @soumeng78 It does, it basically returns the diff between these paths.. which is indeed `d\e`. – CodeCop Feb 03 '23 at 22:37
  • @no_hex - I'm not looking for the difference - I'm looking for relative path a parent level directory. The bigger context is I want to pass the return value to hydra.initialize() method - the intialize method needs the relative path of config directory to the currently running script. the config directory is at the project root level (which I get through git library) and I want to compute on the fly relative directory wrt current script. – soumeng78 Feb 03 '23 at 22:45
  • So you're using the wrong method, you want the output to be `a/b/c`? – CodeCop Feb 03 '23 at 22:46
  • @mkrieger1 - I don't find that solution is using purely pathlib APIs. If I need to use os.path, I can as well use my 1st solution. – soumeng78 Feb 03 '23 at 22:47
  • @no_hex: no the o/p should be exact same as with os.path.relpath() case i.e. "../.." – soumeng78 Feb 03 '23 at 22:48
  • What about this answer? https://stackoverflow.com/a/60671745/ – mkrieger1 Feb 03 '23 at 23:07
  • @mkrieger1 - Except the very last verbose one, all others are using APIs from os.path. My original question was if I can achieve the same thing with just pathlib APIs or not. – soumeng78 Feb 04 '23 at 00:18
  • From what I gather, no, there isn't a way to achieve this strictly with just pathlib Path, but you can gleam how "far back" you have to by getting the length of the `.parts` of the path and building the relative path from that => so length of "d/e" parts is 2, so `"/".join(['..' for e in Path().relative_to().parts])` should in this instance get you what you want, though this might not be 100% fool proof. – Shmack Feb 04 '23 at 02:35
  • @Shmack - thank you. Maybe I'll stick to os.path.relpath() for now. But I'm wondering why this is not supported. – soumeng78 Feb 04 '23 at 03:21
  • I'm really just having a hard time thinking about the application of the idea here. I mean, you know the absolute path to both and you want to compute how far back you have to go? – Shmack Feb 04 '23 at 07:00
  • @Shmack - may or may not be back always. I've 2 paths - current working dir and the config directory for hydra. I need to provide relative path to the config directory to the hydra API. Now, config directory could be few levels up or a sibling or in a different branch wrt some parent (ancestor) level directory. – soumeng78 Feb 04 '23 at 18:26

0 Answers0