]> granicus.if.org Git - python/commitdiff
bpo-32539: Fix OSError for os.listdir() for extended-length paths on Windows (#5169)
authorAnthony Sottile <asottile@umich.edu>
Mon, 15 Jan 2018 21:39:04 +0000 (13:39 -0800)
committerSerhiy Storchaka <storchaka@gmail.com>
Mon, 15 Jan 2018 21:39:04 +0000 (23:39 +0200)
See https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx?f=255&MSPPError=-2147217396#maxpath

Paths that begin with `\\?\` are "extended-length paths".

Lib/test/test_os.py
Misc/NEWS.d/next/Library/2018-01-12-09-20-22.bpo-32539.D7AbdE.rst [new file with mode: 0644]
Modules/posixmodule.c

index aca03fdabb1decaf281c0f733a88bb7926556ff3..84e20e0c013b7536b5aee8d884db06f00e91a8d0 100644 (file)
@@ -900,6 +900,56 @@ class Win32KillTests(unittest.TestCase):
         self._kill_with_event(signal.CTRL_BREAK_EVENT, "CTRL_BREAK_EVENT")
 
 
+@unittest.skipUnless(sys.platform == "win32", "Win32 specific tests")
+class Win32ListdirTests(unittest.TestCase):
+    """Test listdir on Windows."""
+
+    def setUp(self):
+        self.created_paths = []
+        for i in range(2):
+            dir_name = 'SUB%d' % i
+            dir_path = os.path.join(support.TESTFN, dir_name)
+            file_name = 'FILE%d' % i
+            file_path = os.path.join(support.TESTFN, file_name)
+            os.makedirs(dir_path)
+            with open(file_path, 'w') as f:
+                f.write("I'm %s and proud of it. Blame test_os.\n" % file_path)
+            self.created_paths.extend([dir_name, file_name])
+        self.created_paths.sort()
+
+    def tearDown(self):
+        shutil.rmtree(support.TESTFN)
+
+    def test_listdir_no_extended_path(self):
+        """Test when the path is not an "extended" path."""
+        # unicode
+        fs_encoding = sys.getfilesystemencoding()
+        self.assertEqual(
+                sorted(os.listdir(support.TESTFN.decode(fs_encoding))),
+                [path.decode(fs_encoding) for path in self.created_paths])
+
+        # bytes
+        self.assertEqual(
+                sorted(os.listdir(os.fsencode(support.TESTFN))),
+                self.created_paths)
+
+    def test_listdir_extended_path(self):
+        """Test when the path starts with '\\\\?\\'."""
+        # See: http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx#maxpath
+        # unicode
+        fs_encoding = sys.getfilesystemencoding()
+        path = u'\\\\?\\' + os.path.abspath(support.TESTFN.decode(fs_encoding))
+        self.assertEqual(
+                sorted(os.listdir(path)),
+                [path.decode(fs_encoding) for path in self.created_paths])
+
+        # bytes
+        path = b'\\\\?\\' + os.path.abspath(support.TESTFN)
+        self.assertEqual(
+                sorted(os.listdir(path)),
+                self.created_paths)
+
+
 class SpawnTests(unittest.TestCase):
     def _test_invalid_env(self, spawn):
         args = [sys.executable, '-c', 'pass']
diff --git a/Misc/NEWS.d/next/Library/2018-01-12-09-20-22.bpo-32539.D7AbdE.rst b/Misc/NEWS.d/next/Library/2018-01-12-09-20-22.bpo-32539.D7AbdE.rst
new file mode 100644 (file)
index 0000000..cc24a6b
--- /dev/null
@@ -0,0 +1,2 @@
+Fix ``OSError`` for ``os.listdir`` with deep paths (starting with ``\\?\``) on
+windows.  Patch by Anthony Sottile.
index c9886d514b788270056c5768e8203a3e82646b45..cecbb45fb4b3672a1411c8e9f2dc42737f1079d4 100644 (file)
@@ -2385,7 +2385,7 @@ posix_listdir(PyObject *self, PyObject *args)
     if (len > 0) {
         char ch = namebuf[len-1];
         if (ch != SEP && ch != ALTSEP && ch != ':')
-            namebuf[len++] = '/';
+            namebuf[len++] = SEP;
         strcpy(namebuf + len, "*.*");
     }