osdir.com


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Convert Windows paths to Linux style paths


On 3/12/19, Paul Moore <p.f.moore at gmail.com> wrote:
>
> Do you care about case sensitivity (for example, is it important to you
> whether filenames "foo" and "FOO" map to the same file or not on
> Linux, given that they do on Windows)?

That's no longer a given in Windows, since NTFS in Windows 10 supports
case-sensitive directories that override the Windows API. For some
reason they didn't expose this as a file attribute set on the
directory, so it can only be queried using either an NT system call or
the fsutil.exe command-line program.

Our Windows filesystem code (e.g. in pathlib) that assumes
case-insensitive filename matching (e.g. via the casefold, lower, or
upper string methods) is wrong for case-sensitive directories. For
example:

    >>> p = pathlib.Path('C:/CaseSensitive')
    >>> os.system(f'fsutil file queryCaseSensitiveInfo "{p}"')
    Case sensitive attribute on directory C:\CaseSensitive is enabled.
    0
    >>> (p / 'foo').touch()
    >>> (p / 'FOO').touch()
    >>> os.listdir(p)
    ['FOO', 'foo']

Due to pathlib's use of case folding in Windows, globbing "foo" and
"FOO" both match "foo":

    >>> list(p.glob('foo'))
    [WindowsPath('C:/CaseSensitive/foo')]
    >>> list(p.glob('FOO'))
    [WindowsPath('C:/CaseSensitive/foo')]

If we remove "foo", glob('FOO') no longer matches anything since it
checks for the existence of "foo" instead of "FOO":

    >>> os.remove(p / 'foo')
    >>> os.listdir(p)
    ['FOO']
    >>> list(p.glob('FOO'))
    []