Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2 update to pydantic v2 #5

Merged
merged 2 commits into from
Oct 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion environment-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ channels:
- conda-forge
dependencies:
- python
- pydantic=1.9
- pydantic>2
- pydantic-settings
- python-dotenv
- jupyterlab>=3.0.14
- ipywidgets
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
104 changes: 39 additions & 65 deletions src/maplocal/env.py
Original file line number Diff line number Diff line change
@@ -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__)

Expand Down Expand Up @@ -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,
# )
File renamed without changes.
17 changes: 7 additions & 10 deletions tests/test_maplocal.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
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]


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:
Expand All @@ -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)