# Relative versus absolute paths on Windows

Jason R. Coombs jaraco at jaraco.com
Thu Nov 19 17:37:35 CET 2009

The current implementation of Python (2.6.4, 3.1.1) treats \bar as a
relative path but reports it as an absolute path.

>>> ntpath.isabs('\\bar')
True
>>> ntpath.abspath('\\bar')
'C:\\bar'
>>> os.chdir('d:\\')
>>> ntpath.abspath('\\bar')
'd:\\bar'
>>> os.chdir('\\\\server\\share')
>>> ntpath.abspath('\\bar')
'\\\\server\\share\\bar'

In other words, paths without a drive letter are reported as absolute,
but treated as relative, except in a few special cases.

>>> ntpath.join('d:\\foo', '\\bar')
'\\bar'

In this case, \bar is treated as absolute, and not relative to d:\foo.

This inconsistency means that to effectively resolve one path relative
to another, one has to resort to explicit drive letter manipulation.
See http://stackoverflow.com/questions/1654659/find-a-path-in-windows-relative-to-another
for a case in point.

My understanding is that in Windows, a path is only absolute if it
contains a drive letter or it begins with a double-backslash.

Curiously, the .Net Framework seems to be subject to the same
limitation

# using IronPython 2.6RC2
>>> System.IO.Path.IsPathRooted('\\bar')
True
>>> System.IO.Path.Combine('d:\\foo', '\\bar') # expect d:\bar
'\\bar'

The documentation for Combine raises this issue in the Community
Content (http://msdn.microsoft.com/en-us/library/fyy7a5kt.aspx).

Furthermore, the Windows API utility is also consistent with this odd
behavior (http://msdn.microsoft.com/en-us/library/bb773660%28VS.
85%29.aspx).

describes absolute paths consistent with my understanding:

Absolute paths have these characteristics.
Length is at least 2 characters, AND
( Second character is ":", OR First two characters is "\\" )

And according to WikiPedia (http://en.wikipedia.org/wiki/Path_
%28computing%29), "[an] absolute path is a path that points to the
same location on one file system regardless of the working directory."
By this definition, \bar is a relative path on Windows.

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

I've built workarounds in https://svn.jaraco.com/jaraco/python/jaraco.windows/jaraco/windows/filesystem.py
as join() and resolve_path(). I'm happy to continue using these
workarounds, but I wanted to bring this issue to the attention of the
questions.

What is the benefit of treating \path as absolute?
Should Python have built-in support for resolving one path relative to
another (such as is jaraco.windows.filesystem.resolve_path does)?
Given the long established behavior of Python and other platforms for
handling absolute paths in Windows, is there a way forward that
handles these cases more elegantly, or is the best approach to just
mumble something nasty under our breath and work around these issues
on a case-by-case basis?