Author jaraco
Recipients giampaolo.rodola, jafo, jaraco, lemburg, loewis, nnorwitz, swarren
Date 2009-06-05.17:29:30
SpamBayes Score 3.88578e-16
Marked as misclassified No
Message-id <1244222975.47.0.655582517146.issue1578269@psf.upfronthosting.co.za>
In-reply-to
Content
I've now completed all of the aforementioned tasks.

1) Kernel32 does not need to be freed.  It is not freed by other calls
after which this additional code was modeled.  Additionally, the MSDN
indicates that it should only be freed by the module that loaded the
handle (which is not this one).

2) Functions that could be made inline have been made inline.

3) The todo, detection of whether a symlink target is a directory, has
been implemented.

4) A unit test with three tests has been added.  This test has not been
integrated into the larger test suite, but must be run explicitly (for
now).  The unit test passes with no failures on Windows Vista as written.

Some issues still remain.

A) In general, there is a implementation mismatch between Posix and
Windows symlinks.  In particular, Windows maintains that a symlink is
either for a directory or for a file, regardless of the existence of the
target.  Posix instead treats all symlinks like (special) files but
determines the directory status based on the target.  This mismatch
causes more specific problems.

B) Existing unit tests in test_os.py are going to fail (and maybe
others).  In particular, they will fail because they attempt to remove
symlinks to directories using os.remove.  Windows expects the use of
os.rmdir for directory-like symlinks (that is, symlinks who's original
destination was a directory or who's target_is_directory was set to true
at the time it was created).  The unit test included with the patch
illustrates some of these nuances.

C) Because lstat hides the directory status of a symlink (i.e. clears
S_IFLNK), it is not always possible to determine whether a symlink
should be removed using os.remove or os.rmdir.  Specifically, if the
symlink has no target or a directory symlink references a file, the user
will only know to call os.rmdir when os.remove fails with a WindowsError.

I see these issues break down into two categories:

I) How to remove a symlink?
  (a) Should os.remove be rewritten to handle directory symlinks on
Windows?  This method would provide the best compatibility with existing
code.
  (b) Or, do we require python authors to manually determine which
method to call to remove a symlink?  This approach is less intrusive,
but really doesn't provide an effective solution, as it's only partly
compatible with Posix implementations.

II) How to detect a directory symlink?  In either case of (I), there
needs to be an implementation to detect directoryness of a symlink.
  (a) Create a new function in posixmodule that exposes the directory
bit of a symlink, perhaps "is_symlink_directory", which always returns
false except on Windows.
  (b) Change win_lstat to leave the S_IFDIR bit in tact and modify
S_ISLNK to ignore that bit.  Then is_symlink_directory becomes
S_ISDIR(lstat_mode) and S_ISLNK(lstat_mode).

Alternately, maybe trying to fit the Windows APIs into Posix
compatibility is the wrong approach.  Maybe instead there should be a
Python abstraction layer for symlink handling.  I think we're close with
the existing approach, but I'm somewhat worried that we will continue to
find edge cases that break because of the differences in assumptions
about the two implementations.

I think this is getting very close.  I appreciate all the help and support.
History
Date User Action Args
2009-06-05 17:29:36jaracosetrecipients: + jaraco, lemburg, loewis, nnorwitz, jafo, giampaolo.rodola, swarren
2009-06-05 17:29:35jaracosetmessageid: <1244222975.47.0.655582517146.issue1578269@psf.upfronthosting.co.za>
2009-06-05 17:29:34jaracolinkissue1578269 messages
2009-06-05 17:29:33jaracocreate