[Python-Dev] Proposed: add support for UNC paths to all functions in ntpath
Larry Hastings
larry at hastings.org
Wed Apr 29 22:01:38 CEST 2009
I've written a patch for Python 3.1 that changes os.path so it handles
UNC paths on Windows:
http://bugs.python.org/issue5799
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:")
or
>>> os.chdir("c:foo\\bar")
but you can't say
>>> os.chdir("\\\\hostname\\share")
But this is irrelevant to the patch.
Here's what my 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 <http://svn.python.org/view/python/trunk/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. Instead it uses
posixpath.
* 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.
What do you think?
/larry/
More information about the Python-Dev
mailing list