Relative versus absolute paths on Windows

Ethan Furman ethan at stoneleaf.us
Tue Nov 24 00:37:10 CET 2009

Jason R. Coombs wrote:
> On Nov 20, 3:52 pm, Ethan Furman <et... at stoneleaf.us> wrote:
>
>>It is often said on this list that 'Python is not Java'.  It is also
>>true that 'Windows is not Unix'.
>>
>>Unlike the *nix world where there is a *single* root, and everything
>>else is relative to that, in the Windows world there are several roots
>>-- every drive has one!
>
>
> I acknowledge that the Windows paradigm is messy and less elegant than
> Unix. I'm not trying to place blame here. I pointed out that even the
> Windows interfaces don't seem to provide the functions needed to do
> what I want to do. However, my point is that there is a need for path
> resolution that respects a rooted path as relative to another path.

I think for this discussion you would be better off using the word
'combine' rather than 'relative'.

>>So \bar is both an absolute path on whichever drive is active (or
>>specified), as well as relative if you happen to have more than one
>>drive, but it will not ever be relative on any specific drive.  If you
>>want 'bar' to be relative to the current directory, do not specify a
>
>
> Precisely. And my point is that if the path "specified" has a drive (d:
> \foo) and one wants "\bar" relative to d:\foo, the result should be d:
> \bar, not \bar, which is relative to the current drive.

s/relative/combined with/

> I elaborate below.
>
>
>>>Ultimately, I don't care what the definition is. It seems to me,
>>>however, that Python should have a function that can resolve one path
>>>name relative to another, but due to these limitations, it does not. I
>>>should point out that os.path.relpath is not the solution either as
>>>the first parameter is always treated as relative to the current
>>
>>Please note that there *is not* a relative path that can take you from
>>c:\foo to d:\bar  (see the point about multiple roots above).
>
>
> I'm not looking for a relative path from c:\foo to d:\bar. I know the
> "shortest relative path" from c:\foo to d:\bar is the absolute path d:
> \bar. What I am looking for is a way to resolve one path relative to
> another irrespective of the current directory.
>
> Here's the use case: A symlink or shortcut (they can both be treated
> for symbolic links for the sake of this discussion) is defined in a
> particular location, let's say d:\foo. This symlink points to "\bar".
>
> On Windows, the target of the symlink is treated as relative to the
> location of the symlink itself, not the current directory when
> accessed. In other words, \bar relative to d:\foo always resolves to d:
> \bar. To effectively track down the target of a symbolic link, it
> becomes necessary to perform this resolution.
>
>
>>>What is the benefit of treating \path as absolute?
>>
>>That was not Python's decision, but Windows'.
>
>
> Maybe so. My feeling is there's a good reason for it, based on the
> multiple implementations that follow the same approach. Nevertheless,
> that doesn't change the fact that despite the APIs, Windows does

The multiple implementations exist because that's the way is has always
been on the Microsoft side.  You have to play by their rules if you are
going to use their OS.

>>>Should Python have built-in support for resolving one path relative to
>>>another (such as is jaraco.windows.filesystem.resolve_path does)?
>>
>>As I noted above, you are not returning a relative path when the paths
>>cross drive letter boundaries, or one of the paths specified is a
>>drive-absolute path (such as '\bar').
>
>
> To be clear, I'm not trying to find a relative path between two paths.
> I'm trying to resolve one path relative to another. On Unix,
> os.path.join does this. On Windows, there is no such function (except
> jaraco.windows.filesystem.join).
>
>
>>Hope this helps.
>
>
> Thanks for taking the time to write a detailed response. I think I
> understand the problem. What is frustrating is that the current
> behavior seems buggy (others words, not mine) and a function that does
> what many would expect isn't available.
>
>
>>P.S.
>>And now that I look up the comments in the bug-tracker, I see this was
>>all already pointed out to you.
>
>
> Based on the name and specification, I expected something different
> from relpath, but after the discussion, I decided it wasn't the tool I
> was seeking.

relpath is definitely not the tool you are looking for.  I do agree with
you that a function to combine two paths would be very handy... of
course, since relpath does work if the current drive is the one
specified (I think, haven't tested that statement), a wrapper function
that saved the current path, then switched drives, did the relpath
lookup, then switched back...  hmmmm -- that would be a pain if the
drive didn't exist on the system doing the work... oh well.

Yup, if your function works, keep it!  :D

~Ethan~