On Sun, 24 Oct 2010 18:55:05 -0700 (PDT) "Edward K. Ream" <[email protected]> wrote:
> https://bugs.launchpad.net/leo-editor/+bug/613153 > > I'm willing to put in a patch for this bug, especially if it is > confined go g.os_path_isabs. > > Does anyone have thoughts or code? I have some incomplete code, but this is the Windows drive relative path issue we were just discussing. I think the fix can be confined to g.os_path_isabs *and* g.os_path_join, probably with a helper, g.os_path_is_drive_relative. in non-patch form here's the code I currently have - I think it's nearly done but I wanter to add a unit test which would fail before and work after, and I think that might have been waiting on the "getPathFromDirectives doesn't pass a directory creation flag" issue, which you just recently addressed. I'll look at it more tomorrow. Cheers -Terry def os_path_isabs(path): """Normalize the path and convert it to an absolute path. """ if os_path_win_drive_relative(path): return False else: path = g.toUnicodeFileEncoding(path) return os.path.isabs(path) def os_path_win_drive_relative(path): """ Return True if this is a Windows drive-root-relative path which os.path.isabs unhelpfully calls "absolute". According to os.path.isabs(), in Windows, "\\foo\\bar.leo" is an absolute path, but resolving it depends of the python process's current directory. See http://bugs.python.org/issue1669539. So in cases where we seem to be dealing with an "absolute" path of this kind in Windows, we need to prepend the drive letter based on any relevant @path directives and the location of the .leo file. Therefore, such paths are not really absolute. """ return ( path and (path[0] == "\\" or path[0] == "/") and # avoid \\server\share\path cases (len(path) < 2 or path[1] != path[0]) and (sys.platform in ("win32", "cygwin") or True) ) def os_path_win_drive_relative_fix(args): """ Tweak a list of directories about to be passed to os.path.join (in os_path_join) to compensate for Windows drive relative paths, *see os_path_win_drive_relative()*. Although this code bails if it encounters a drive relative path before seeing a path with defines the current drive, that should not happen in normal Leo operations, because the first path list entry is usually the absolute path to the .leo file. """ drive = None # 'current' drive ans = [] # modified list for i in args: if (len(i) >= 2 and 'a' <= i[0].lower() <= 'z' and i[1] == ':'): # 'a:' defines drive drive = i[0:2] elif i.startswith('\\\\'): # '\\server\share' defines drive drive = '\\\\'+'\\'.join(i[2:].split('\\', 2)[:2]) elif i.startswith('//'): # '//server/share' defines drive drive = '//'+'/'.join(i[2:].split('/', 2)[:2]) if os_path_win_drive_relative(i): if not drive: # no useful resolution at this point return # return without change ans = [ "%s%s" % (drive, i) ] else: ans.append(i) # leave on the list for os_path_join args[:] = ans def os_path_join(*args,**keys): trace = False and not g.unitTesting c = keys.get('c') uargs = [g.toUnicodeFileEncoding(arg) for arg in args] if trace: g.trace('1',uargs) # Note: This is exactly the same convention as used by getBaseDirectory. if uargs and uargs[0] == '!!': uargs[0] = g.app.loadDir elif uargs and uargs[0] == '.': c = keys.get('c') if c and c.openDirectory: uargs[0] = c.openDirectory # g.trace(c.openDirectory) uargs = [g.os_path_expanduser(z) for z in uargs if z] if trace: g.trace('2',uargs) if any(map(os_path_win_drive_relative, uargs)): os_path_win_drive_relative_fix(uargs) path = os.path.join(*uargs) if trace: g.trace('3',path) # May not be needed on some Pythons. path = g.toUnicodeFileEncoding(path) return path -- You received this message because you are subscribed to the Google Groups "leo-editor" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/leo-editor?hl=en.
