4
votes

Note: this question is about the newly supported win32 long paths (available since Windows 10 Version 1607, Build 14352) and not about extended UNC paths starting with \\?\.


I enabled long path support via a group policy and rebooted my PC. I checked in the registry that both HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\FileSystem\LongPathsEnabled and HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem\LongPathsEnabled are set to 1.

Then I opened a Python REPL and tried to create a directory that will exceed the 260-char limit, but failed:

>>> import os

>>> longdirname = 'a' * 300

>>> longdirname
'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'

>>> os.makedirs(longdirname)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "c:\python27\lib\os.py", line 157, in makedirs
    mkdir(name, mode)
WindowsError: [Error 3] The system cannot find the path specified: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
[Error 3] The system cannot find the path specified: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'

I'm assuming that the long path support somehow didn't take effect here. Why is this and how can I properly enable it so that it works from Python scripts?


Update: I also tried directly calling a Win32 API function via pywin32 that claims in its documentation that it should support long paths, but failed again:

>>> import win32file

>>> longname = 'a' * 300

>>> win32file.CreateDirectoryW(longname, None)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
error: (3, 'CreateDirectoryW', 'The system cannot find the path specified.')
(3, 'CreateDirectoryW', 'The system cannot find the path specified.')

Update 2: Also tried creating via individual components:

>>> for i in range(1, 300):
...     win32file.CreateDirectoryW('a', None)
...     os.chdir('a')
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
error: (206, 'CreateDirectoryW', 'The filename or extension is too long.')
(206, 'CreateDirectoryW', 'The filename or extension is too long.')

(os.makedirs also won't work in this case)


Update 3: The following batch script will not fail:

@echo off

setlocal enableextensions enabledelayedexpansion

pushd

set /a count = 1
for /L %%i in (1,1,300) do (
  mkdir a
  cd a
  echo %%i
)
endlocal

popd

So I'm assuming that this is somehow related to Python then.

1
I'm wondering if there isn't a limit for the name themselves. Have you tried a long dirname that represents a tree (separated by slashes) ? - Jean-François Fabre♦
@Jean-FrançoisFabre Good suggestion and I was excited to try it, but unfortunately it does not work - see my update in the post. - Tamás Szelei
did you try from a classic CMD before trying in python? - Jean-François Fabre♦
@Jean-FrançoisFabre Great suggestion again, and brings closer to the solution: a batch script will happily create a path of 300 deep directories named a. See my update. - Tamás Szelei
I'll give it a go tonight if noone answered. I have admin privileges at home :) - Jean-François Fabre♦

1 Answers

2
votes

The solution is both simple and somewhat disappointing: Python versions prior to 3.6 are not able to take advantage of long paths. 3.6 changelist.

Windows historically has limited path lengths to 260 characters. This meant that paths longer than this would not resolve and errors would result.

In the latest versions of Windows, this limitation can be expanded to approximately 32,000 characters. Your administrator will need to activate the “Enable Win32 long paths” group policy, or set the registry value HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem@LongPathsEnabled to 1.

This allows the open() function, the os module and most other path functionality to accept and return paths longer than 260 characters when using strings. (Use of bytes as paths is deprecated on Windows, and this feature is not available when using bytes.)

After changing the above option, no further configuration is required.

Changed in version 3.6: Support for long paths was enabled in Python.

To prove that it works, I did the following:

Python 3.6.2 (v3.6.2:5fd33b5, Jul  8 2017, 04:14:34) [MSC v.1900 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> longdir = 'a' * 300
>>> os.makedirs(longdir)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\tamas\AppData\Local\Programs\Python\Python36-32\lib\os.py", line 220, in makedirs
    mkdir(name, mode)
OSError: [WinError 123] The filename, directory name, or volume label syntax is incorrect: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
>>> for i in range(1, 300):
...     os.mkdir('a')
...     os.chdir('a')
...
>>> len(os.getcwd())
631
>>>

The first makedirs call fails because individual components are still limited to 255 characters.