classification
Title: win32 os.path.normpath not correct for leading slash cases
Type: behavior Stage: test needed
Components: Library (Lib), Windows Versions: Python 2.6
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: amaury.forgeotdarc, facundobatista, gergan, sdeibel
Priority: normal Keywords:

Created on 2003-01-09 21:42 by sdeibel, last changed 2009-07-07 14:54 by amaury.forgeotdarc. This issue is now closed.

Files
File name Uploaded Description Edit
normpath-fix.py sdeibel, 2004-11-17 04:15 Replacement impl that we use (since my original pasted fct is munged also)
Messages (9)
msg13960 - (view) Author: Stephan R.A. Deibel (sdeibel) Date: 2003-01-09 21:42
os.path.normpath on win32 misses two cases in its
duplicate slash
removal code that I believe should be dealt with:

c:\\x\y\z
\\\x\y\z

Both of these are returned unchanged.

I've attached an implementation that fixes these to
return the following, respectively:

c:\x\y\z
\\x\y\z

I did see the other normpath bugs that were reported
and rejected
and think that the above isn't also a case of "garbage
in garbage out" but of course there's room for
interpretation.

I am a bit unsure about the UNC case since Posix
collapses only 3+ leading slashes to a single slash and
otherwise leaves up to two slashes.  But in the context
of win32 the above seems to make more sense to me.

Thanks,

Stephan Deibel
Wing IDE Developer
Archaeopteryx Software

--------------------

def normpath(path):
    """Normalize path, eliminating double slashes, etc."""
    path = path.replace("/", "\\")
    prefix, path = os.path.splitdrive(path)
    if prefix == '':
        max_leading = 2
    else:
        max_leading = 1
    i = 0
    while path[:1] == "\\":
        if i < max_leading:
            prefix = prefix + "\\"
            i += 1
        path = path[1:]
    comps = path.split("\\")
    i = 0
    while i < len(comps):
        if comps[i] in ('.', ''):
            del comps[i]
        elif comps[i] == '..':
            if i > 0 and comps[i-1] != '..':
                del comps[i-1:i+1]
                i -= 1
            elif i == 0 and prefix.endswith("\\"):
                del comps[i]
            else:
                i += 1
        else:
            i += 1
    # If the path is now empty, substitute '.'
    if not prefix and not comps:
        comps.append('.')
    return prefix + "\\".join(comps)
msg13961 - (view) Author: Facundo Batista (facundobatista) * (Python committer) Date: 2004-11-16 23:17
Logged In: YES 
user_id=752496

Please, could you verify if this problem persists in Python 2.3.4
or 2.4?

If yes, in which version? Can you provide a test case?

If the problem is solved, from which version?

Note that if you fail to answer in one month, I'll close this bug
as "Won't fix".

Thank you! 

.    Facundo
msg13962 - (view) Author: Facundo Batista (facundobatista) * (Python committer) Date: 2004-11-16 23:17
Logged In: YES 
user_id=752496

Don't understand what you're proposing: in Py2.4b2 (Win2K
SP4) I got:

>>> os.path.normpath("c:\\x\y\z")
'c:\\x\\y\\z'

and that seems ok to me.

.    Facundo
msg13963 - (view) Author: Stephan R.A. Deibel (sdeibel) Date: 2004-11-17 04:00
Logged In: YES 
user_id=12608

The c:\\x\y\z case was broken up to 2.3.4 but appears fixed
in 2.4b2, as you noticed (it used to return "c:\\\\x\\y\\z"
and now returns "c:\\x\\y\\z" as it
should).

However in 2.4b4 the \\x\y\z case still returns
"\\\\x\\y\\z" (it
returns any number of leading backslashes unchanged, no
matter how 
many are passed in):

>>> os.path.normpath(r"\\x\y\z")
'\\\\x\\y\\z'
>>> os.path.normpath(r"\\\x\y\z")
'\\\\\\x\\y\\z'

I'm still fairly sure it should return "\\x\\y\\z" instead
as the more appropriate 
normalization of this kind of path on win32.

Hope that helps!  Thanks for your work on clearing the bug list!
msg13964 - (view) Author: Stephan R.A. Deibel (sdeibel) Date: 2004-11-17 04:04
Logged In: YES 
user_id=12608

Good god, notification email is munging the number of
backslashes inconsistently depending on quoting -- see the
sf bug entry in a browser to see the right thing.  Sorry
about that!
msg13965 - (view) Author: Facundo Batista (facundobatista) * (Python committer) Date: 2004-11-19 20:25
Logged In: YES 
user_id=752496

I've the following behaviour in 2.4b1:

>>> os.path.normpath(r"\x\y\z")
'\\x\\y\\z'
>>> os.path.normpath(r"\x\\y\z")
'\\x\\y\\z'
>>> os.path.normpath(r"\x\y\\z")
'\\x\\y\\z'

which is ok to me, and

>>> os.path.normpath(r"\\x\y\z")
'\\\\x\\y\\z'

which seems bad.

I'm setting this bug to the 2.4 group.
msg13966 - (view) Author: gergan (gergan) Date: 2005-07-19 16:50
Logged In: YES 
user_id=1301159

I'm experiencing the same bug on linux with
Python 2.4.1 (#1, Jun 28 2005, 21:03:32) 
[GCC 3.4.4 (Gentoo 3.4.4, ssp-3.4.4-1.0, pie-8.7.8)]
all the paths beginning with double slash are left unchanged
from os.path.normpath.
so expected behaviour would be (as stated in the documentation)
>>>os.path.normpath ("//usr/lib")
'/usr/lib'
the actual result is:
>>>os.path.normpath ("//usr/lib")
'//usr/lib'
msg13967 - (view) Author: gergan (gergan) Date: 2005-07-19 16:59
Logged In: YES 
user_id=1301159

nevermind, it actually is not a bug as the comment says it all 
# POSIX allows one or two initial slashes, but treats three
or more
# as single slash.
I didn't know this. Excuse me and forget my posting ::))
msg90236 - (view) Author: Amaury Forgeot d'Arc (amaury.forgeotdarc) * (Python committer) Date: 2009-07-07 14:54
On Windows, os.path.normpath(r"\\x\y\z") must return the string
unchanged, because this is the syntax for UNC paths:
    \\server\share\file.txt

Closing as invalid.
History
Date User Action Args
2009-07-07 14:54:27amaury.forgeotdarcsetstatus: open -> closed

nosy: + amaury.forgeotdarc
messages: + msg90236

resolution: not a bug
2009-02-12 20:02:06ajaksu2setstage: test needed
type: behavior
components: + Windows
versions: + Python 2.6, - Python 2.4
2003-01-09 21:42:03sdeibelcreate