[Python-Dev] Tests broken on Windows

Tim Peters tim.peters at gmail.com
Mon Nov 1 02:26:33 CET 2004

[Johannes Gijsbers]
> Hum, I didn't realize os.chmod() worked this differently on Windows.

Well, it can't work the same.  At the chmod() level, there are no
"user", "group" or "world"/"other" concepts on Windows.  There also
aren't distinct "execute"/"search", "write" and "read" bits.  There
are "hidden", "system", and "archive" bits on Windows, which have no
equivalents on Unix, and there's a "read only" bit on Windows, setting
which is kind of like turning off 0222 on Unix.  The only thing
chmod() is useful for on Windows is fiddling the state of the "read
only" bit.

> Seems like I bumped into bug #755617 (os module: Need a better description
> of "mode"). Per that bug, I googled for '_chmod msdn' and came up with the
> attached patch.  However, I don't have a Windows machine handy to test. Could
> someone with a Windows machine try the patch?

No cigar.  The patched test appears to assume that if you strip write
permission from a directory, that also makes it impossible to delete
files within the directory.  But directories on Windows aren't files
-- they're directories <wink>.

The attached patch allows the test to pass on WinXP, although I'm not
sure about Win95/98/ME.  If there are no objections, I'll check it in.
 I don't remember enough about Unix's equally obscure permission
gimmicks to be sure that this patch will leave the test working on
non-Windows boxes.
-------------- next part --------------
Index: Lib/test/test_shutil.py
RCS file: /cvsroot/python/python/dist/src/Lib/test/test_shutil.py,v
retrieving revision 1.8
diff -u -r1.8 test_shutil.py
--- Lib/test/test_shutil.py	31 Oct 2004 12:05:31 -0000	1.8
+++ Lib/test/test_shutil.py	1 Nov 2004 01:10:32 -0000
@@ -1,4 +1,3 @@
 # Copyright (C) 2003 Python Software Foundation
 import unittest
@@ -20,21 +19,28 @@
         def test_on_error(self):
             self.errorState = 0
-            f = open(os.path.join(TESTFN, 'a'), 'w')
+            self.childpath = os.path.join(TESTFN, 'a')
+            f = open(self.childpath, 'w')
-            # Make TESTFN unwritable.
-            os.chmod(TESTFN, stat.S_IRUSR)
+            old_dir_mode = os.stat(TESTFN).st_mode
+            old_child_mode = os.stat(self.childpath).st_mode
+            # Make unwritable.
+            os.chmod(self.childpath, stat.S_IREAD)
+            os.chmod(TESTFN, stat.S_IREAD)
             shutil.rmtree(TESTFN, onerror=self.check_args_to_onerror)
-            # Make TESTFN writable again.
-            os.chmod(TESTFN, stat.S_IRWXU)
+            # Make writable again.
+            os.chmod(TESTFN, old_dir_mode)
+            os.chmod(self.childpath, old_child_mode)
+            # Clean up.
     def check_args_to_onerror(self, func, arg, exc):
         if self.errorState == 0:
             self.assertEqual(func, os.remove)
-            self.assertEqual(arg, os.path.join(TESTFN, 'a'))
+            self.assertEqual(arg, self.childpath)
             self.assertEqual(exc[0], OSError)
             self.errorState = 1

More information about the Python-Dev mailing list