0

I have a python script running on windows that just copies contents of a directory from one location to other but am running into following error,not sure why ,i can confirm the source file is present,any idea on what could be wrong here?

 File "C:\crmapps\apps\python275-64\lib\shutil.py", line 208, in copytree
    raise Error, errors
shutil.Error: [('\\\\WPLBD04\\pkg\\builds\\promote\\2712\\2712_QCA1990ANFC_CNSS.HW_SP.2.0_win_pro\\sumatraservices\\inRexW\\TLM-2009-07-15\\docs\\doxygen\\html\\classtlm__utils_1_1instance__specific__extensions__per__accessor-members.html', '\\\\sun\\sscn_dev_integration\\promote_per_CL_artifacts\\TECH_PRO.CNSS.2.0\\20141013125710_1115240\\2712_QCA1990ANFC_CNSS.HW_SP.2.0_win_pro\\sumatraservices\\inRexW\\TLM-2009-07-15\\docs\\doxygen\\html\\classtlm__utils_1_1instance__specific__extensions__per__accessor-members.html', "[Errno 2] No such file or directory:
user3830867
  • 3
  • 1
  • 2
  • 2
    That second path is more than 255 characters long - on some Windows filesystems that's still an issue if I remember correctly. – Lukas Graf Oct 14 '14 at 22:21
  • Sure looks like a path spelled wrong to me... are you sure the full target path exists and is spelled correctly? – Paul Becotte Oct 14 '14 at 22:33
  • @LukasGraf i did a test on mac python 2.7 with 320 Characters, not a problem with shutil.copy2() & shutil.copyfile(). Maybe it's different on windows – user1767754 Oct 14 '14 at 22:44
  • If nothing helps post your windows version, filesystem type and the shutil call. – wenzul Oct 14 '14 at 22:56
  • You can look if anything [here](http://stackoverflow.com/questions/18390341/unable-to-locate-files-with-long-names-on-windows-with-python) helps you. You might need to use `\\?\UNC\\` format. Python has wrappers around windows unicode calls - [link](https://hg.python.org/cpython/file/111d535b52e8/Python/fileutils.c#l763). So if you stick to unicode names you might get lucky. – luk32 Oct 15 '14 at 00:22

2 Answers2

2

As mentioned, you have gone beyond the win32 path size limit. It turns out that the limit is in win32 and not the actual file system drivers. The trick to solving the problem is to prepend r"\\?\" to the path so that win32 will pass the paths along without mucking with them. It only works if you use absolute names including drive letter.

def win32_fix_long_path(path):
    return r'\\?\' + os.path.realpath(path)

It likely won't work in all situations, especially if you try to pass the name to a subprocess.

tdelaney
  • 73,364
  • 6
  • 83
  • 116
0

Like Lukas Graf said. The problem is that your destination path seems to be 266 characters long and therefore exceeds the limit.

The destination path is longer. So the error always will be in the destination because your source already exists. Assumed that your source path is not a extended-length path.

source: \\WPLBD04\pkg\builds\promote\2712\
destination: \\sun\sscn_dev_integration\promote_per_CL_artifacts\TECH_PRO.CNSS.2.0\20141013125710_1115240\
  1. You could try to shorten your filepath with win32api to may avoid this problem.

    string = win32api.GetShortPathName(path)

  2. You can prepend \\?\ to use extended-length paths.

>>> open(r"C:\%s\%s" % ("a"*1, "a"*254),"w")
<open file '...', mode 'w' at 0x0000000001F120C0>
>>> open(r"C:\%s\%s" % ("a"*2, "a"*254),"w")
IOError: [Errno 2] No such file or directory: '...'
>>> open(r"C:\%s\%s" % ("a"*1, "a"*255),"w")
IOError: [Errno 2] No such file or directory: '...'
>>> open(r"\\?\C:\%s\%s" % ("a"*1, "a"*255),"w")
<open file '\\\\?\\...', mode 'w' at 0x0000000001F12150>

Exaggerated: I don't think there is any noticable side effect on file access speed with extended-length paths. If you just want to avoid extended-length paths use a destination path which length is less than or equal to source path.

wenzul
  • 3,948
  • 2
  • 21
  • 33
  • Are you sure? How can it shorten the path with out losing anything. The docs only say it converts `path` to 8.3 filename with full path. Not to mention docs linked are for python 2.5. – luk32 Oct 14 '14 at 22:36
  • @luk32 Look at an output of [`dir /X`](https://superuser.com/questions/348079/how-can-i-find-the-short-path-of-a-windows-directory-file). There the short name for not 8.3 names will be listed. Directories will be the first 6 letters followed by `~1`, `~2`... – wenzul Oct 14 '14 at 22:49
  • But the problem begins with the fact, that windows cannot have folders longer then 255 characters, so it has nothing to do with shutil not beeing available to copy as it seem.s – user1767754 Oct 14 '14 at 22:51
  • @user1767754 This could be the case... I looked [here](https://stackoverflow.com/questions/1065993/has-windows-7-fixed-the-255-character-file-path-limit). Maybe it helps to pass the path in unicode not ascii. – wenzul Oct 14 '14 at 22:55
  • @wenzul - this gives an error pywintypes.error: (2, 'GetShortPathName', 'The system cannot find the file specified.') – user3830867 Oct 14 '14 at 23:27
  • @wenzul So you want to go back to DOS naming conventions? This is a crazy idea. Are you sure, all windows versions will support it? If it worked, it would be a shady, ticking time bomb, workaround =/. The problem lies within the underlying call to windows API, which limits paths to 255. [Relevant documentation](http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx#maxpath). If any chance I would try using unicode path string, and pray `shutil` call this "unicode versions", to allow ~32k paths. – luk32 Oct 14 '14 at 23:34
  • @luk32 I agree, it's quick and dirty. :) Unicode is the way to go. – wenzul Oct 14 '14 at 23:37
  • @wenzul Well, to be fair, it worked here: http://stackoverflow.com/questions/18390341/unable-to-locate-files-with-long-names-on-windows-with-python, at least for local files. They also suggested the `\\\\?\\+path` for network volumes. ... windows @_@. – luk32 Oct 14 '14 at 23:54