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.

Reply via email to