How to get native windows path inside msys python?

4.2k views Asked by At

When inside msys2-Python (3.4.3), how am I supposed to get the native windows path of some file from the msys-filesystem?

I want to write a configuration file for a native windows application so the msys path rewriting does not come into account.

There is a solution, but I don't like it, because I have to feed an unknown path into a shell:

path = "/home/user/workspace"
output = subprocess.check_output( 'cmd //c echo ' + path, shell = True )

This returns C:/msys64/home/user/workspace.

This question is not really a duplicate of Convert POSIX->WIN path, in Cygwin Python, w/o calling cygpath because it is about msys2.

2

There are 2 answers

3
David Grayson On

MSYS2 comes with a utility named cygpath that you can use. Run cygpath -w NAME. cygpath is a command-line utility in /usr/bin that you can run the same way you would run any other command-line utility. The output will be a Windows-style path corresponding to the NAME argument you passed.

0
Uwe Koloska On

Based on this great answer https://stackoverflow.com/a/38471976/5892524 here is the same code rewritten to be used inside msys2.

import ctypes
import sys

xunicode = str if sys.version_info[0] > 2 else eval("unicode")

# If running under Msys2 Python, just use DLL name
# If running under non-Msys2 Windows Python, use full path to msys-2.0.dll
# Note Python and msys-2.0.dll must match bitness (i.e. 32-bit Python must
# use 32-bit msys-2.0.dll, 64-bit Python must use 64-bit msys-2.0.dll.)
msys = ctypes.cdll.LoadLibrary("msys-2.0.dll")
msys_create_path = msys.cygwin_create_path
msys_create_path.restype = ctypes.c_void_p
msys_create_path.argtypes = [ctypes.c_int32, ctypes.c_void_p]

# Initialise the msys DLL. This step should only be done if using
# non-msys Python. If you are using msys Python don't do this because
# it has already been done for you.
if sys.platform != "msys":
    msys_dll_init = msys.msys_dll_init
    msys_dll_init.restype = None
    msys_dll_init.argtypes = []
    msys_dll_init()

free = msys.free
free.restype = None
free.argtypes = [ctypes.c_void_p]

CCP_POSIX_TO_WIN_A = 0
CCP_POSIX_TO_WIN_W = 1
CCP_WIN_A_TO_POSIX = 2
CCP_WIN_W_TO_POSIX = 3

def win2posix(path):
    """Convert a Windows path to a msys path"""
    result = msys_create_path(CCP_WIN_W_TO_POSIX, xunicode(path))
    if result is None:
        raise Exception("msys_create_path failed")
    value = ctypes.cast(result, ctypes.c_char_p).value
    free(result)
    return value

def posix2win(path):
    """Convert a msys path to a Windows path"""
    result = msys_create_path(CCP_POSIX_TO_WIN_W, str(path))
    if result is None:
        raise Exception("msys_create_path failed")
    value = ctypes.cast(result, ctypes.c_wchar_p).value
    free(result)
    return value