[python-win32] ValueError in relpath

Niemann, Hartmut hartmut.niemann at siemens.com
Wed Sep 12 18:33:53 CEST 2012


Hello!
 
I am not subscribed to this mailing list (so CC me on all replies please), 
but I encountered something that looks like a Windows related bug to me and hope that somebody knows
how to take care of it in the python way.
 
I have a tool that traverses and compares large file trees. Occasionally it fails with:
 
  File "F:\doublettenweg.py", line 53, in removedups
    relfilename = os.path.relpath(oldfilename,oldroot)
  File "C:\Python27\lib\ntpath.py", line 512, in relpath
    % (path_prefix, start_prefix))
ValueError: path is on drive , start on drive F:
 
I found out, that (in C:\Python27\lib\ntpath.py)
path_prefix is empty because internally nt._getfullpathname(path) is used, which silently
returns path on error (which is relative). So relpath(), which converts both paths to absolute paths
and has them split into parts, will try to split a relative path into drive and path, 
which leads to the ValueError I see.

This is Python 2.7.3 on Windows XP.
 
My conclusions:
 
(1) I wonder what limitation on windows was hit by the _getfullpathname(path) call. 
The file name is long but not so exceptionally long. Maybe this is a python problem
that can be fixed?
 
(2) The fact that abspath(path) swallows the windows error, returning
something that is definitely wrong (a relative path where an absolute
one is expected) makes it hard to use it safely. Could it simply
not catch the WindowsError or raise an Error (which one?)?
 
(3) why does relpath() need absolute paths at all? Could it work without this
path normalisation if both paths are relative and path.startswith(start) is true?
 

With best regards
 
Hartmut Niemann
 
 
 
 
Additional information:
this part of my program
------8<------------
    try:
     relfilename = os.path.relpath(oldfilename,oldroot)
    except ValueError as e:
        print ("os.path.relpath failed:")
        print ("path = ", repr(oldfilename))
        print ("start = ", repr(oldroot))
        print ("_abspath_split(path) returns ", ntpath._abspath_split(oldfilename))
        print ("normpath(path) = ", ntpath.normpath(oldfilename))
        print ("abspath(normpath(path)) = ", ntpath.abspath(ntpath.normpath(oldfilename)))
        try:
            print ("_getfullpathname(path) = ", _getfullpathname(oldfilename))
        except:
            print ("_getfullpathname(path) failed.")
        raise e
-----8<-------
 
prints out:
----8<------
os.path.relpath failed:
path =  '2012-08-07_diffzu_2012-09-12\\PRJ\\I1SITRAC\\wrk\\130_Eclipse\\Workspace\\.metadata\\.plugins\\com.python.pydev.analysis\\python_v1_eo3pb4rfuku7u65tfbb
ltnbp5\\v1_indexcache\\pylint.test.input.func_noerror_classes_meth_could_be_a_function_bhwc.v1_indexcache'
start =  '2012-08-07_diffzu_2012-09-12'
_abspath_split(path) returns  (False, '', ['2012-08-07_diffzu_2012-09-12', 'PRJ', 'I1SITRAC', 'wrk', '130_Eclipse', 'Workspace', '.metadata', '.plugins', 'com.p
ython.pydev.analysis', 'python_v1_eo3pb4rfuku7u65tfbbltnbp5', 'v1_indexcache', 'pylint.test.input.func_noerror_classes_meth_could_be_a_function_bhwc.v1_indexcac
he'])
normpath(path) =  2012-08-07_diffzu_2012-09-12\PRJ\I1SITRAC\wrk\130_Eclipse\Workspace\.metadata\.plugins\com.python.pydev.analysis\python_v1_eo3pb4rfuku7u65tfbb
ltnbp5\v1_indexcache\pylint.test.input.func_noerror_classes_meth_could_be_a_function_bhwc.v1_indexcache
abspath(normpath(path)) =  2012-08-07_diffzu_2012-09-12\PRJ\I1SITRAC\wrk\130_Eclipse\Workspace\.metadata\.plugins\com.python.pydev.analysis\python_v1_eo3pb4rfuk
u7u65tfbbltnbp5\v1_indexcache\pylint.test.input.func_noerror_classes_meth_could_be_a_function_bhwc.v1_indexcache
_getfullpathname(path) failed.
Traceback (most recent call last):
  File "F:\doublettenweg.py", line 115, in <module>
    removedups(args.oldroot, args.newroot, args.testrun)
  File "F:\doublettenweg.py", line 68, in removedups
    raise e
ValueError: path is on drive , start on drive F:
----8<-------
 
This is the relevant abspath implementation in C:\Python27\lib\ntpath.py:
----8<-----
else:  # use native Windows method on Windows
    def abspath(path):
        """Return the absolute version of a path."""
 
        if path: # Empty path must return current working directory.
            try:
                path = _getfullpathname(path)
            except WindowsError:
                pass # Bad path - return unchanged.
        elif isinstance(path, unicode):
            path = os.getcwdu()
        else:
            path = os.getcwd()
        return normpath(path)
----8<-----
 
 
 

Mit freundlichen Grüßen
Dr. Hartmut Niemann 

Siemens AG 
Infrastructure & Cities Sector
Rail Systems Division
Locomotives and Components 
IC RL LOC EN LE 8 
Werner-von-Siemens-Str. 67 
91052 Erlangen, Deutschland 
Tel.: +49 9131 7-34264 
Fax: +49 9131 7-26254 
mailto:hartmut.niemann at siemens.com 

Siemens Aktiengesellschaft: Vorsitzender des Aufsichtsrats: Gerhard Cromme; Vorstand: Peter Löscher, Vorsitzender; Roland Busch, Brigitte Ederer, Klaus Helmrich, Joe Kaeser, Barbara Kux, Hermann Requardt, Siegfried Russwurm, Peter Y. Solmssen, Michael Süß; Sitz der Gesellschaft: Berlin und München, Deutschland; Registergericht: Berlin Charlottenburg, HRB 12300, München, HRB 6684; WEEE-Reg.-Nr. DE 23691322 




More information about the python-win32 mailing list