How do I normalize a path format to Unix-style while on Windows?

Question:

I am storing paths in a json file using a python script. I want the paths to be stored in the same format (Unix-style) no matter which OS the script is run on. So basically I want to run the os.path.normpath function, but it only converts paths to Unix-style instead of changing its function depending on the host OS. What is the best way to do this?

Asked By: ahelwer

||

Answers:

You can convert Windows-style path to UNIX-style after calling os.path.normpath. The conversion can be conveniently done with pathlib.PureWindowsPath.as_posix:

import os.path
from pathlib import PureWindowsPath

path = r'foo\bar'
path = os.path.normpath(path)
if os.path.sep == '\':
    path = PureWindowsPath(path).as_posix()
print(path)

This outputs, in Windows:

/foo/bar
Answered By: blhsing

There are four cases to handle, all of which should output a normalized Posix path:

  1. Windows path on Posix system
  2. Posix path on Posix system
  3. Windows path on Windows system
  4. Posix path on Windows system

The other answer is close but doesn’t handle all of these. This does:

from os.path import normpath
from pathlib import PureWindowsPath

def convert(path):
    return PureWindowsPath(normpath(PureWindowsPath(path).as_posix())).as_posix()

print('Windows path: ' + convert(r'.pathto..tofile'))
print('Posix path: ' + convert('./path/to/../to/file'))

which will output the following on both Windows and Posix systems:

Windows path: path/to/file
Posix path: path/to/file

Two nested PureWindowsPath instances are necessary to handle case 1, Windows path on a Posix system. If you don’t care about that case and only need to handle the other three cases, a single nested call is sufficient:

def convert(path):
    return PureWindowsPath(normpath(path)).as_posix()

Since normpath is able to normalize Posix paths on Windows, but normath does not normalize Windows paths on Posix systems.

Answered By: ahelwer
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.