classification
Title: Value error 'path is on drive c: start on drive d:' in os.path.relpath
Type: behavior Stage:
Components: Windows Versions: Python 3.1, Python 2.6
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: jaraco, ncoghlan
Priority: normal Keywords:

Created on 2009-10-23 21:39 by jaraco, last changed 2009-11-01 01:23 by ncoghlan. This issue is now closed.

Messages (6)
msg94394 - (view) Author: Jason R. Coombs (jaraco) * (Python committer) Date: 2009-10-23 21:39
A simple test fails:

Python 2.6.3 (r263rc1:75186, Oct 2, 2009, 20:40:30) [MSC v.1500 32 bit
(Intel)] on win32
>>> import os
>>> os.path.relpath('\\bar', 'd:\\')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\python\lib\ntpath.py", line 487, in relpath
    % (path_list[0], start_list[0]))
ValueError: path is on drive C:, start on drive d:

If I change the current directory to 'E:\', the error changes to "path
is on drive E:, start on drive d:".

Clearly, relpath is doing some calculations based on the current
directory, although the documentation states that it should be
performing a relative path calculation based on the supplied start
("D:\" in this case).

In Python 3.1.1, the error is "path is on mount 'C:', start on mount 'd:'"

os.path.relpath should be able to perform relative path calculations
regardless of the current directory, or the documentation should explain
why the current directory is relevant when start is supplied.
msg94744 - (view) Author: Nick Coghlan (ncoghlan) * (Python committer) Date: 2009-10-31 05:00
It's not the current directory that's the problem, it's the current
drive. Windows has no absolute root directory - instead, it has a root
directory for each drive. That means that "\\dir" is a path relative to
the current drive rather than an absolute path. You need to put the
drive letter in there to make it an absolute path.

That's just a fact of life when working with the windows file system,
rather than anything specific to Python or os.path.relpath.
msg94755 - (view) Author: Jason R. Coombs (jaraco) * (Python committer) Date: 2009-10-31 13:50
Based on the response, then the documentation is inadequate. I don't
want to make a stink about this, but I think the issue is still
unresolved. If it would be better to discuss this elsewhere, please advise.

The documentation says "Return a relative filepath to path either from
the current directory or from an optional start point".

The documentation should say "Return a relative filepath to a path,
where path is considered relative to the current directory, either from
the current directory or from an optional start point. On Windows, a
ValueError is raised if the current directory and the start path are not
on the same drive."

The clarification is that the path specified is _not_ relative to the
start point (which would have been my guess), but is relative to another
unspecified environmental condition (the current directory). To leave
out this clarification means that this implicit behavior is left to the
user to discover rather than to state that it's by design.

For my purposes, I wanted a function that would calculate a target based
on a start path and a relative or absolute path from it. Based on the
documentation, I thought relpath was it.

I understand better now what the purpose of relpath is, and it's not
what I was expecting. I think the documentation could be improved to
help manage this expectation for other users.
msg94758 - (view) Author: Nick Coghlan (ncoghlan) * (Python committer) Date: 2009-10-31 14:53
The path *returned* is relative to the start point. The target path is
figured out normally (i.e. relative to the current directory if an
absolute path is not given).

In your example, you aren't passing in an absolute Windows path - you
give a path relative to the current drive (since no drive is specified).

Windows file pathing is hopeless, but it isn't the job of Python's
documentation to explain its quirks.
msg94759 - (view) Author: Jason R. Coombs (jaraco) * (Python committer) Date: 2009-10-31 15:19
The documentation changes I suggested make no mention to Windows pathing
quirks. They instead clarify two aspects:

1) cross-platform behavior (how the path is interpreted) and
2) platform-specific implementation of relpath (what Python exceptions
to expect in exceptional conditions).

These two changes would have made it clear to me from the beginning that
relpath is not what I was searching for when I wanted to find a path
from one path to another. I'm just trying to help those who come after
me to not run into the same situation.
msg94780 - (view) Author: Nick Coghlan (ncoghlan) * (Python committer) Date: 2009-11-01 01:23
os.relpath *does* give you a relative path between two directories.

The problem you are encountering is that, on Windows, a relative path
doesn't even *exist* if the two directories are on different drives
(which is exactly what the error message says).
History
Date User Action Args
2009-11-01 01:23:20ncoghlansetmessages: + msg94780
2009-10-31 15:19:41jaracosetmessages: + msg94759
2009-10-31 14:53:46ncoghlansetmessages: + msg94758
2009-10-31 13:50:57jaracosetmessages: + msg94755
2009-10-31 05:00:30ncoghlansetstatus: open -> closed

nosy: + ncoghlan
messages: + msg94744

resolution: not a bug
2009-10-23 21:39:22jaracocreate