Skip to content

Commit 27f32e9

Browse files
asottileserhiy-storchaka
authored andcommitted
bpo-32539: Fix OSError for os.listdir() for extended-length paths on Windows (#5169)
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".
1 parent ab95b30 commit 27f32e9

File tree

3 files changed

+53
-1
lines changed

3 files changed

+53
-1
lines changed

Lib/test/test_os.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -900,6 +900,56 @@ def test_CTRL_BREAK_EVENT(self):
900900
self._kill_with_event(signal.CTRL_BREAK_EVENT, "CTRL_BREAK_EVENT")
901901

902902

903+
@unittest.skipUnless(sys.platform == "win32", "Win32 specific tests")
904+
class Win32ListdirTests(unittest.TestCase):
905+
"""Test listdir on Windows."""
906+
907+
def setUp(self):
908+
self.created_paths = []
909+
for i in range(2):
910+
dir_name = 'SUB%d' % i
911+
dir_path = os.path.join(support.TESTFN, dir_name)
912+
file_name = 'FILE%d' % i
913+
file_path = os.path.join(support.TESTFN, file_name)
914+
os.makedirs(dir_path)
915+
with open(file_path, 'w') as f:
916+
f.write("I'm %s and proud of it. Blame test_os.\n" % file_path)
917+
self.created_paths.extend([dir_name, file_name])
918+
self.created_paths.sort()
919+
920+
def tearDown(self):
921+
shutil.rmtree(support.TESTFN)
922+
923+
def test_listdir_no_extended_path(self):
924+
"""Test when the path is not an "extended" path."""
925+
# unicode
926+
fs_encoding = sys.getfilesystemencoding()
927+
self.assertEqual(
928+
sorted(os.listdir(support.TESTFN.decode(fs_encoding))),
929+
[path.decode(fs_encoding) for path in self.created_paths])
930+
931+
# bytes
932+
self.assertEqual(
933+
sorted(os.listdir(os.fsencode(support.TESTFN))),
934+
self.created_paths)
935+
936+
def test_listdir_extended_path(self):
937+
"""Test when the path starts with '\\\\?\\'."""
938+
# See: http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx#maxpath
939+
# unicode
940+
fs_encoding = sys.getfilesystemencoding()
941+
path = u'\\\\?\\' + os.path.abspath(support.TESTFN.decode(fs_encoding))
942+
self.assertEqual(
943+
sorted(os.listdir(path)),
944+
[path.decode(fs_encoding) for path in self.created_paths])
945+
946+
# bytes
947+
path = b'\\\\?\\' + os.path.abspath(support.TESTFN)
948+
self.assertEqual(
949+
sorted(os.listdir(path)),
950+
self.created_paths)
951+
952+
903953
class SpawnTests(unittest.TestCase):
904954
def _test_invalid_env(self, spawn):
905955
args = [sys.executable, '-c', 'pass']
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix ``OSError`` for ``os.listdir`` with deep paths (starting with ``\\?\``) on
2+
windows. Patch by Anthony Sottile.

Modules/posixmodule.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2385,7 +2385,7 @@ posix_listdir(PyObject *self, PyObject *args)
23852385
if (len > 0) {
23862386
char ch = namebuf[len-1];
23872387
if (ch != SEP && ch != ALTSEP && ch != ':')
2388-
namebuf[len++] = '/';
2388+
namebuf[len++] = SEP;
23892389
strcpy(namebuf + len, "*.*");
23902390
}
23912391

0 commit comments

Comments
 (0)