Normalizing path strings and separators in cross-platform unit test scripts

eryk sun eryksun at gmail.com
Mon Jan 7 22:31:10 EST 2019


On 1/7/19, Chris Angelico <rosuav at gmail.com> wrote:
> On Tue, Jan 8, 2019 at 5:52 AM Malcolm Greene <python at bdurham.com> wrote:
>>
>> Is there a best practice way to convert Windows style paths (with
>> backslash path separators) to Linux style paths with forward slash path
>> separators? I've looked at the os and pathlib libraries without seeing
>> anything that describes our need.
>> Any downsides to this approach?

Use os.path.normpath to compare apples to apples, as was mentioned in
another post.

> If you are confident you'll never have an actual backslash in a path
> name (which would be a requirement if they're cross-platform anyway),
> you could just p.replace("\\", "/") to convert them. I don't think
> that will break anything on any Windows-based or Unix-based OS (could
> be wrong of course).

Windows Trivia

The only 'file system' I know of that allows slashes (forward or back)
in names is the named-pipe file system. This is stretching of course
because it's not a general-purpose file system, and in particular it
doesn't support directories.

Some system components and applications create named pipes with
backslash in the name. For example:

    >>> print(*sorted(n for n in os.listdir('//./pipe') if '\\' in n), sep='\n')
    GoogleCrashServices\S-1-5-18
    GoogleCrashServices\S-1-5-18-x64
    PIPE_EVENTROOT\CIMV2SCM EVENT PROVIDER
    Winsock2\CatalogChangeListener-178-0
    Winsock2\CatalogChangeListener-210-0
    Winsock2\CatalogChangeListener-214-0
    Winsock2\CatalogChangeListener-2a4-0
    Winsock2\CatalogChangeListener-2ac-0
    Winsock2\CatalogChangeListener-3c0-0
    Winsock2\CatalogChangeListener-7fc-0

(The CIMV2SCM pipe is created by the Windows Management
Instrumentation system service. The Winsock pipes are created by
processes that call WSAProviderConfigChange to wait for Winsock
provider configuration changes. The template for the variable suffix
is "-{process_id:x}-{sequence_number}". On this system I also have
pipes created by GoogleCrashHandler[64].exe, which is running as the
SYSTEM account, with SID S-1-5-18.)

A regular '\\\\.\\' device path gets normalized to translate forward
slashes to backslashes, so in practice we don't see pipes with forward
slash in the name. To show that's it's possible, we can use a
'\\\\?\\' extended device path to prevent normalizing the path. For
example:

    >>> h = CreateNamedPipe(r'\\?\pipe\name/with/slashes', 3, 0, 1, 0,
0, 0, None)
    >>> print(*(n for n in os.listdir('//./pipe') if '/' in n), sep='\n')
    name/with/slashes



More information about the Python-list mailing list