[New-bugs-announce] [issue5799] Change ntpath functions to implicitly support UNC paths

Larry Hastings report at bugs.python.org
Mon Apr 20 13:07:14 CEST 2009

New submission from Larry Hastings <larry at hastings.org>:

This patch changes "ntpath" so all functions handle UNC paths.

In a Windows path string, a UNC path functions *exactly* like a drive
letter.  This patch means that the Python path split/join functions
treats them as if they were.

For instance:
    >>> splitdrive("A:\\FOO\\BAR.TXT")
    ("A:", "\\FOO\\BAR.TXT")

With this patch applied:
    >>> splitdrive("\\\\HOSTNAME\\SHARE\\FOO\\BAR.TXT")
    ("\\\\HOSTNAME\\SHARE", "\\FOO\\BAR.TXT")

This methodology only breaks down in one place: there is no "default
directory" for a UNC share point.  E.g. you can say
    >>> os.chdir("c:")
    >>> os.chdir("c:foo\\bar")
but you can't say
    >>> os.chdir("\\\\hostname\\share")

The attached patch changes:
* Modify join, split, splitdrive, and ismount to add explicit support
  for UNC paths.  (The other functions pick up support from these four.)
* Simplify isabs and normpath, now that they don't need to be delicate
  about UNC paths.
* Modify existing unit tests and add new ones.
* Document the changes to the API.
* Deprecate splitunc, with a warning and a documentation remark.

This patch adds one subtle change I hadn't expected.  If you call
split() with a drive letter followed by a trailing slash, it returns the
trailing slash as part of the "head" returned.  E.g.
    >>> os.path.split("\\")
    ("\\", "")
    >>> os.path.split("A:\\")
    ("A:\\", "")
This is mentioned in the documentation, as follows:
    Trailing slashes are stripped from head unless it is the root
    (one or more slashes only).

For some reason, when os.path.split was called with a UNC path with only
a trailing slash, it stripped the trailing slash:
    >>> os.path.split("\\\\hostname\\share\\")
    ("\\\\hostname\\share", "")
My patch changes this behavior; you would now see:
    >>> os.path.split("\\\\hostname\\share\\")
    ("\\\\hostname\\share\\", "")
I think it's an improvement--this is more consistent.  Note that this
does *not* break the documented requirement that
os.path.join(os.path.split(path)) == path; that continues to work fine.

In the interests of full disclosure: I submitted a patch providing this
exact behavior just over ten years ago.  GvR accepted it into Python
1.5.2b2 (marked "*EXPERIMENTAL*") and removed it from 1.5.2c1.

You can read GvR's commentary upon removing it; see comments in
Misc/HISTORY dated "Tue Apr  6 19:38:18 1999".  If memory serves
correctly, the "problems" cited were only on Cygwin.  At the time Cygwin
used "ntpath", and it supported "//a/foo" as an alias for "A:\\FOO". 
You can see how this would cause Cygwin problems.

In the intervening decade, two highly relevant things have happened:
* Python no longer uses ntpath for os.path on Cygwin.  It instead uses
* Cygwin removed the "//a/foo" drive letter hack.  In fact, I believe it
now support UNC paths.
Therefore this patch will have no effect on Cygwin users.

p.s. I discussed this patch with Mark Hammond at the CPython sprint at
PyCon 2008.  I therefore added him to the nosy list.  I have no idea if
this is proper etiquette; I apologize in advance if it is not.

components: Windows
files: lch.ntpath.r71757.diff
keywords: patch
messages: 86195
nosy: lhastings, mhammond
severity: normal
status: open
title: Change ntpath functions to implicitly support UNC paths
type: feature request
versions: Python 3.1
Added file: http://bugs.python.org/file13723/lch.ntpath.r71757.diff

Python tracker <report at bugs.python.org>

More information about the New-bugs-announce mailing list