Source code for mypythontools.paths.wsl_paths

"""Module with functions for 'wsl_paths' class.

!! This is just copy pasted from https://github.com/psychonaute/wsl-pathlib/blob/master/wsl_pathlib/path.py !!
to remove unnecessary requirements.
"""
from os import name as os_name
from pathlib import PosixPath, PurePosixPath, PureWindowsPath, WindowsPath, Path

base = WindowsPath
if os_name == "posix":
    base = PosixPath


[docs]def get_drive_letter(path_in, mnt: bool): """Return the letter of the windows drive of the path.""" if mnt: return path_in[5].lower() return path_in[0].lower()
[docs]def is_mnt(path_in: str): """Check if the path posix and lives in '/mnt/'.""" return path_in[:5] == "/mnt/"
[docs]def is_nt(path_in: str): """Check if the path is a windows path.""" return path_in[1] == ":"
[docs]class WslPath(base): """This is just copy pasted from https://github.com/psychonaute/wsl-pathlib/blob/master/wsl_pathlib/path.py Extend pathlib.Path by addding the properties wsl_path and win_path. depending on the plateform base class either pathlib's PosixPath or WindowsPath. Path objects are instanciated with path representation matching the user's OS. Both _wsl_path and _win_path properties are lazily converted for their getters, the first time they are requested. """ def __new__(cls, *args, **kwargs): r"""Correction of the path, to instanciate the version matching the os. Crude correction of the path string, in order to instanciate a representation of the matching the user's OS. ie: we are on wsl and we instanciated WslPath('c:\foo') we change the path str to instanciate PosixPath('/mnt/c/foo'). """ path_in = str(args[0]).replace("\\", "/") path_in = Path(path_in).resolve().as_posix() if is_mnt(path_in): if os_name == "posix": crude_path = path_in else: dl = get_drive_letter(path_in, mnt=True) crude_path = f"{dl.upper()}:/{path_in[7:]}" elif is_nt(path_in): if os_name == "nt": crude_path = path_in # simply check if path start with "/mnt/" to detect WSL path else: dl = get_drive_letter(path_in, mnt=False) crude_path = f"/mnt/{dl}{path_in[2:]}" else: raise NotImplementedError( "Posix Path not in /mnt/ not yet supported", ) new_args = list(args) new_args[0] = crude_path args = tuple(new_args) return super().__new__(cls, *args, **kwargs) def __init__(self, *args, **kwargs): """Initialize WslPath properties after base init.""" super().__init__() self._init_wsl_path() @property def wsl_path(self) -> str: """Initialise WslPath properties and return lazy loaded value. If the Path object had been created by other mean than a direct instanciation, ie: p2 = p1 / "add_on", then initialize the WslPath properties now. Then builds WindowsPath the win_path if it was not yet being build. Then returns the string representation of it. """ try: self.drive_letter except AttributeError: self._init_wsl_path() if not self._wsl_path: rel_parts = list(self._win_path.parts[1:]) rel_parts.insert(0, f"/mnt/{self.drive_letter}") self._wsl_path = PurePosixPath(*rel_parts) return str(self._wsl_path) @property def win_path(self) -> str: """Initialise WslPath properties and return lazy loaded value. If the Path object had been created by other mean than a direct instanciation, ie: p2 = p1 / "add_on", then initializes the WslPath properties now. Then builds wsl_path if it was not yet being build. Then returns the string representation of it. """ try: self.drive_letter except AttributeError: self._init_wsl_path() if not self._win_path: rel_parts = list(self._wsl_path.parts[3:]) rel_parts.insert(0, f"{self.drive_letter.upper()}:\\") self._win_path = PureWindowsPath(*rel_parts) return str(self._win_path) def _init_wsl_path(self) -> None: """Idying input path platform and getting the drive letter. Detects the input path as Unix or Win and save it to either _wsl_path or _win_path. Then determine the drive letter that gonna be used during the lazy load. _wsl_path: properties that holds a PurePosixPath object containing the windows reprensetation of the path. _win_path: properties that holds a PureWindowsPath object containing the windows reprensetation of the path. _self.drive_letter: contains the letter of the windows drive. """ path_in = self.as_posix() self._wsl_path = None self._win_path = None if is_nt(path_in): self._win_path = PureWindowsPath(self) else: self._wsl_path = PurePosixPath(self) if self._win_path: self.drive_letter = get_drive_letter( str(self._win_path), mnt=False, ) else: self.drive_letter = get_drive_letter(str(self._wsl_path), mnt=True)