Implement #1578269. Patch by Jason R. Coombs.

Added Windows support for os.symlink when run on Windows 6.0 or greater,
aka Vista. Previous Windows versions will raise NotImplementedError
when trying to symlink.

Includes numerous test updates and additions to test_os, including
a symlink_support module because of the fact that privilege escalation
is required in order to run the tests to ensure that the user is able
to create symlinks. By default, accounts do not have the required
privilege, so the escalation code will have to be exposed later (or
documented on how to do so). I'll be following up with that work next.

Note that the tests use ctypes, which was agreed on during the PyCon
language summit.
This commit is contained in:
Brian Curtin 2010-07-08 21:39:08 +00:00
parent 0dd8f7890a
commit d40e6f70a5
18 changed files with 1161 additions and 275 deletions

View file

@ -16,7 +16,8 @@ __all__ = ["normcase","isabs","join","splitdrive","split","splitext",
"getatime","getctime", "islink","exists","lexists","isdir","isfile",
"ismount", "expanduser","expandvars","normpath","abspath",
"splitunc","curdir","pardir","sep","pathsep","defpath","altsep",
"extsep","devnull","realpath","supports_unicode_filenames","relpath"]
"extsep","devnull","realpath","supports_unicode_filenames","relpath",
"samefile",]
# strings representing various path-related bits and pieces
# These are primarily for export; internally, they are hardcoded.
@ -309,16 +310,28 @@ def dirname(p):
return split(p)[0]
# Is a path a symbolic link?
# This will always return false on systems where posix.lstat doesn't exist.
# This will always return false on systems where os.lstat doesn't exist.
def islink(path):
"""Test for symbolic link.
On WindowsNT/95 and OS/2 always returns false
"""Test whether a path is a symbolic link.
This will always return false for Windows prior to 6.0
and for OS/2.
"""
return False
try:
st = os.lstat(path)
except (os.error, AttributeError):
return False
return stat.S_ISLNK(st.st_mode)
# alias exists to lexists
lexists = exists
# Being true for dangling symbolic links is also useful.
def lexists(path):
"""Test whether a path exists. Returns True for broken symbolic links"""
try:
st = os.lstat(path)
except (os.error, WindowsError):
return False
return True
# Is a path a mount point? Either a root (with or without drive letter)
# or an UNC path with at most a / or \ after the mount point.
@ -612,3 +625,17 @@ def relpath(path, start=curdir):
if not rel_list:
return _get_dot(path)
return join(*rel_list)
# determine if two files are in fact the same file
def samefile(f1, f2):
"Test whether two pathnames reference the same actual file"
try:
from nt import _getfinalpathname
return _getfinalpathname(f1) == _getfinalpathname(f2)
except (NotImplementedError, ImportError):
# On Windows XP and earlier, two files are the same if their
# absolute pathnames are the same.
# Also, on other operating systems, fake this method with a
# Windows-XP approximation.
return abspath(f1) == abspath(f2)