diff --git a/environment-dev.yml b/environment-dev.yml index 92a32df..01c8f5a 100644 --- a/environment-dev.yml +++ b/environment-dev.yml @@ -7,7 +7,8 @@ channels: - conda-forge dependencies: - python - - pydantic=1.9 + - pydantic>2 + - pydantic-settings - python-dotenv - jupyterlab>=3.0.14 - ipywidgets \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 48dc861..28b0007 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ classifiers = [ "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", ] -dependencies = ["pydantic"] +dependencies = ["pydantic>2, pydantic-settings"] dynamic = ["version"] [project.urls] diff --git a/src/maplocal/env.py b/src/maplocal/env.py index f47bf22..f08a439 100644 --- a/src/maplocal/env.py +++ b/src/maplocal/env.py @@ -1,10 +1,11 @@ -from pydantic import BaseModel, BaseSettings, Field, validator import pathlib import importlib.util import sys import typing as ty import os import logging +from pydantic import Field, model_validator +from pydantic_settings import BaseSettings, SettingsConfigDict logger = logging.getLogger(__name__) @@ -41,83 +42,56 @@ def get_maplocal_path(): class MapLocalEnv(BaseSettings): MAPLOCAL_OS_FROM: str = "linux" # TODO make enum MAPLOCAL_OS_TO: str = "windows" - MAPLOCAL_FROM: ty.Optional[pathlib.PurePath] = None - MAPLOCAL_TO: ty.Optional[pathlib.PurePath] = None - MAPLOCAL_SCRIPT_PATH: ty.Optional[pathlib.Path] = None - openpath: ty.Optional[ty.Callable[[pathlib.Path], bool]] = None - runcmd: ty.Optional[ty.Callable[[str], None]] = None - - @validator("MAPLOCAL_FROM", always=True, pre=True) - def _MAPLOCAL_FROM(cls, v, values): - if v is None: - return None - else: - return MAPOS[values["MAPLOCAL_OS_FROM"]](v) - - @validator("MAPLOCAL_TO", always=True, pre=True) - def _MAPLOCAL_TO(cls, v, values): - if v is None: - return None + MAPLOCAL_FROM: ty.Optional[pathlib.PurePath] = Field(None) + MAPLOCAL_TO: ty.Optional[pathlib.PurePath] = Field(None) + MAPLOCAL_SCRIPT_PATH: ty.Optional[pathlib.Path] = Field(None) + openpath: ty.Optional[ty.Callable[[pathlib.Path], bool]] = Field(None) + runcmd: ty.Optional[ty.Callable[[str], None]] = Field(None) + + @model_validator(mode="after") + @classmethod + def _set_values(cls, data: ty.Any): + if data.MAPLOCAL_FROM is None: + data.MAPLOCAL_FROM = MAPOS[data.MAPLOCAL_OS_FROM]("/home") else: - return MAPOS[values["MAPLOCAL_OS_TO"]](v) + data.MAPLOCAL_FROM = MAPOS[data.MAPLOCAL_OS_FROM](data.MAPLOCAL_FROM) - @validator("MAPLOCAL_SCRIPT_PATH", always=True, pre=True) - def _MAPLOCAL_SCRIPT_PATH(cls, v, values): - if v is None: + if data.MAPLOCAL_TO is None: + data.MAPLOCAL_TO = MAPOS[data.MAPLOCAL_OS_TO](f"\\\\wsl.localhost\\{os.environ['WSL_DISTRO_NAME']}\\home") + else: + data.MAPLOCAL_TO = MAPOS[data.MAPLOCAL_OS_TO](data.MAPLOCAL_TO) + + if data.MAPLOCAL_SCRIPT_PATH is None: p = get_maplocal_path() if p.is_file(): - return p + data.MAPLOCAL_SCRIPT_PATH = p else: - return None + data.MAPLOCAL_SCRIPT_PATH = pathlib.Path(__file__).parent / "maplocal_wsl.py" else: - p = pathlib.Path(v) + p = pathlib.Path(data.MAPLOCAL_SCRIPT_PATH) if p.is_file(): - return p + data.MAPLOCAL_SCRIPT_PATH = p else: logger.warning(f"for maplocal to load openpath and runcmd callable, {str(p)} must exist with functions `openpath` and `runcmd`") - return None - - - @validator("openpath", always=True) - def _openpath(cls, v, values): - if "MAPLOCAL_SCRIPT_PATH" not in values: - return None - p = values["MAPLOCAL_SCRIPT_PATH"] + + if "MAPLOCAL_SCRIPT_PATH" not in data.model_fields: + data.openpath = None + p = data.MAPLOCAL_SCRIPT_PATH if p is not None: - return load(p, "openpath") + data.openpath = load(p, "openpath") else: - return None + data.openpath = None - @validator("runcmd", always=True) - def _runcmd(cls, v, values): - if "MAPLOCAL_SCRIPT_PATH" not in values: - return None - p = values["MAPLOCAL_SCRIPT_PATH"] - if p is not None: - return load(p, "runcmd") + if "MAPLOCAL_SCRIPT_PATH" not in data.model_fields: + data.runcmd = None else: - return None - - class Config: - # env_file = PATH_ENV - env_file_encoding = "utf-8" - arbitrary_types_allowed=True + p = data.MAPLOCAL_SCRIPT_PATH + if p is not None: + data.runcmd = load(p, "runcmd") + else: + data.runcmd = None + return data -if __name__ == "__main__": + model_config = SettingsConfigDict(env_file_encoding="utf-8", arbitrary_types_allowed=True) - DIR_REPO = pathlib.Path("/home/jovyan/maplocal") - PATH_ENV = DIR_REPO / "tests" / ".env" - PATH_SCRIPT = DIR_REPO / "scripts" / "maplocal_wsl.py" - assert PATH_ENV.is_file() - MAPENV = MapLocalEnv(_env_file=PATH_ENV) - print('done') - # DIR_REPO = pathlib.Path(__file__).parents[2] - # PATH_ENV = DIR_REPO / ".env" - # PATH_SCRIPT = DIR_REPO / "scripts" / "maplocal_wsl.py" - # # assert PATH_ENV.is_file() - # MAPENV = MapLocalEnv( - # MAPLOCAL_FROM="/home/jovyan", - # MAPLOCAL_TO="\\\\wsl$\\20221021\\home\\jovyan", - # MAPLOCAL_SCRIPT_PATH=PATH_SCRIPT, - # ) diff --git a/scripts/maplocal_wsl.py b/src/maplocal/maplocal_wsl.py similarity index 100% rename from scripts/maplocal_wsl.py rename to src/maplocal/maplocal_wsl.py diff --git a/tests/test_maplocal.py b/tests/test_maplocal.py index e9e5c63..b917589 100644 --- a/tests/test_maplocal.py +++ b/tests/test_maplocal.py @@ -1,11 +1,9 @@ -from maplocal.maplocal import _remove_root, maplocal -import os import pathlib import typing as ty -import pytest -from maplocal.maplocal import MAPENV, openlocal, runlocal from maplocal.env import MapLocalEnv +from maplocal.maplocal import _remove_root, openlocal, maplocal +MAPENV = MapLocalEnv() PATH_TEST = pathlib.Path(__file__) DIR_REPO = PATH_TEST.parents[1] @@ -13,7 +11,7 @@ class TestMAPENV: def test_MAPENV(self): assert MAPENV.MAPLOCAL_FROM == pathlib.PurePosixPath("/home") - assert MAPENV.MAPLOCAL_TO == pathlib.PureWindowsPath('//wsl.localhost/20221021/home') + assert MAPENV.MAPLOCAL_TO == pathlib.PureWindowsPath('//wsl.localhost/ubuntu_2004_jovyan/home') class TestRemoveRoot: @@ -25,17 +23,16 @@ def test__remove_root(self): class TestMapLocal: def test_map_local(self): - path = maplocal(PATH_TEST) + path = maplocal(PATH_TEST, oldroot=MAPENV.MAPLOCAL_FROM, newroot=MAPENV.MAPLOCAL_TO) assert ( str(path) - == '\\\\wsl.localhost\\20221021\\home\\jovyan\\maplocal\\tests\\test_maplocal.py' + == "\\\\wsl.localhost\\ubuntu_2004_jovyan" + str(PATH_TEST).replace("/", "\\") ) - print(path) - print("done") class TestWslExample: def test_map_local(self): - openlocal(PATH_TEST) + """This will open the file in windows explorer""" + openlocal(PATH_TEST, mapenv=MAPENV) assert isinstance(MAPENV.openpath, ty.Callable)