5

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?

0

2 Answers 2

7

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
Sign up to request clarification or add additional context in comments.

Comments

2

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'.\path\to\..\to\file'))
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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.