From 82fadda351deae612841206cc30727577e3255d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20F=C3=B6rster?= Date: Fri, 14 Mar 2025 11:49:50 +0100 Subject: [PATCH] renaming and add pickling --- src/dopt_basics/{paths.py => io.py} | 41 +++++++++++++++++- tests/{test_paths.py => test_io.py} | 65 ++++++++++++++++++++--------- 2 files changed, 85 insertions(+), 21 deletions(-) rename src/dopt_basics/{paths.py => io.py} (83%) rename tests/{test_paths.py => test_io.py} (72%) diff --git a/src/dopt_basics/paths.py b/src/dopt_basics/io.py similarity index 83% rename from src/dopt_basics/paths.py rename to src/dopt_basics/io.py index 02acbc8..1fd7643 100644 --- a/src/dopt_basics/paths.py +++ b/src/dopt_basics/io.py @@ -1,12 +1,51 @@ from __future__ import annotations +import pickle import shutil from collections.abc import Sequence from pathlib import Path +from typing import Any from dopt_basics.datetime import TIMEZONE_CEST, get_timestamp +def save_pickle( + obj: Any, + folder: Path, + filename: str, + create_folder: bool = False, +) -> None: + pth_file = prepare_path( + folder, + None, + filename=filename, + suffix=".pkl", + create_folder=create_folder, + ) + if not pth_file.parent.exists(): + raise FileNotFoundError( + "The directory structure disered seems not to exist. " + "Consider using >create_folder=True<" + ) + + with open(pth_file, "wb") as pkl_handle: + pickle.dump(obj, pkl_handle, protocol=5) + + +def load_pickle( + folder: Path, + filename: str, +) -> Any: + pth_file = prepare_path(folder, None, filename=filename, suffix=".pkl") + if not pth_file.parent.exists(): + raise FileNotFoundError(f"File not found under: >{pth_file}<") + + with open(pth_file, "rb") as pkl_handle: + obj = pickle.load(pkl_handle) + + return obj + + def create_folder( path: Path, delete_existing: bool = False, @@ -16,7 +55,7 @@ def create_folder( path.mkdir(parents=True, exist_ok=True) -def prepare_save_path( +def prepare_path( root_folder: Path, dirs: Sequence[str] | None, filename: str | None, diff --git a/tests/test_paths.py b/tests/test_io.py similarity index 72% rename from tests/test_paths.py rename to tests/test_io.py index 1644b1e..5c1c7f9 100644 --- a/tests/test_paths.py +++ b/tests/test_io.py @@ -2,7 +2,7 @@ from pathlib import Path import pytest -from dopt_basics import paths +from dopt_basics import io FILE_SEARCH = "test.txt" @@ -28,6 +28,33 @@ def target_file_pth(base_folder) -> Path: return target_file +def test_save_load_pickle_Success(tmp_path): + save_obj = (1, 2, 3, 4, 5) + filename = "TEST" + io.save_pickle(save_obj, tmp_path, filename) + loaded = io.load_pickle(tmp_path, filename) + assert save_obj == loaded + + +def test_save_load_pickle_SuccessCreateFolders(tmp_path): + save_obj = (1, 2, 3, 4, 5) + filename = "TEST" + tmp_path = tmp_path / "test/dir/" + io.save_pickle(save_obj, tmp_path, filename, create_folder=True) + loaded = io.load_pickle(tmp_path, filename) + assert save_obj == loaded + + +def test_save_load_pickle_FailNonExistingFolders(tmp_path): + save_obj = (1, 2, 3, 4, 5) + filename = "TEST" + tmp_path = tmp_path / "test/dir/" + with pytest.raises(FileNotFoundError): + io.save_pickle(save_obj, tmp_path, filename, create_folder=False) + with pytest.raises(FileNotFoundError): + _ = io.load_pickle(tmp_path, filename) + + @pytest.mark.parametrize( "delete_existing", [True, False], @@ -35,10 +62,10 @@ def target_file_pth(base_folder) -> Path: def test_create_folder(tmp_path, delete_existing): target_dir = tmp_path / "test" assert not target_dir.exists() - paths.create_folder(target_dir, delete_existing=delete_existing) + io.create_folder(target_dir, delete_existing=delete_existing) assert target_dir.exists() assert target_dir.is_dir() - paths.create_folder(target_dir, delete_existing=delete_existing) + io.create_folder(target_dir, delete_existing=delete_existing) assert target_dir.exists() assert target_dir.is_dir() @@ -49,7 +76,7 @@ def test_prepare_save_path_SuccessWithCreate(tmp_path): filename = None suffix = None target_pth = tmp_path / "/".join(dirs) - res_pth = paths.prepare_save_path(base_folder, dirs, filename, suffix, create_folder=True) + res_pth = io.prepare_path(base_folder, dirs, filename, suffix, create_folder=True) assert res_pth.exists() assert res_pth == target_pth @@ -59,7 +86,7 @@ def test_prepare_save_path_SuccessWithCreateTimestamp(tmp_path): dirs = ("target", "dir") filename = "test" suffix = ".pkl" - res_pth = paths.prepare_save_path( + res_pth = io.prepare_path( base_folder, dirs, filename, suffix, create_folder=True, include_timestamp=True ) assert res_pth.parent.exists() @@ -71,9 +98,7 @@ def test_prepare_save_path_SuccessWithoutCreate(tmp_path): filename = None suffix = None target_pth = tmp_path / "/".join(dirs) - res_pth = paths.prepare_save_path( - base_folder, dirs, filename, suffix, create_folder=False - ) + res_pth = io.prepare_path(base_folder, dirs, filename, suffix, create_folder=False) assert not res_pth.exists() assert res_pth == target_pth @@ -84,7 +109,7 @@ def test_prepare_save_path_FailNoTargets(tmp_path): filename = None suffix = None with pytest.raises(ValueError): - _ = paths.prepare_save_path( + _ = io.prepare_path( base_folder, dirs, filename, @@ -99,7 +124,7 @@ def test_prepare_save_path_FailNoFilenameSuffix(tmp_path): filename = None suffix = "pkl" with pytest.raises(ValueError): - _ = paths.prepare_save_path( + _ = io.prepare_path( base_folder, dirs, filename, @@ -110,7 +135,7 @@ def test_prepare_save_path_FailNoFilenameSuffix(tmp_path): filename = "test" suffix = None with pytest.raises(ValueError): - _ = paths.prepare_save_path( + _ = io.prepare_path( base_folder, dirs, filename, @@ -125,7 +150,7 @@ def test_prepare_save_path_FailTimestampWithoutFilename(tmp_path): filename = None suffix = None with pytest.raises(ValueError): - _ = paths.prepare_save_path( + _ = io.prepare_path( base_folder, dirs, filename, @@ -141,7 +166,7 @@ def test_prepare_save_path_FailBadSuffix(tmp_path): filename = "test" suffix = "." with pytest.raises(ValueError): - _ = paths.prepare_save_path( + _ = io.prepare_path( base_folder, dirs, filename, @@ -157,7 +182,7 @@ def test_prepare_save_path_SuccessSuffixAddDot(tmp_path): filename = "test" suffix = "pkl" target_path = tmp_path / f"{filename}.{suffix}" - ret_path = paths.prepare_save_path( + ret_path = io.prepare_path( base_folder, dirs, filename, @@ -171,13 +196,13 @@ def test_prepare_save_path_SuccessSuffixAddDot(tmp_path): def test_search_cwd(monkeypatch, base_folder, target_file_pth): monkeypatch.setattr(Path, "cwd", lambda: base_folder) assert Path.cwd() == base_folder - ret = paths.search_cwd(FILE_SEARCH) + ret = io.search_cwd(FILE_SEARCH) assert ret is None target_folder = target_file_pth.parent monkeypatch.setattr(Path, "cwd", lambda: target_folder) assert Path.cwd() == target_folder - ret = paths.search_cwd(FILE_SEARCH) + ret = io.search_cwd(FILE_SEARCH) assert ret is not None assert ret == target_file_pth @@ -185,7 +210,7 @@ def test_search_cwd(monkeypatch, base_folder, target_file_pth): @pytest.mark.parametrize("stop_folder_name", ["to", "base", None]) def test_search_file_iterative(base_folder, target_file_pth, stop_folder_name): # target in parent of 'to': 'path' - ret = paths.search_file_iterative(base_folder, FILE_SEARCH, stop_folder_name) + ret = io.search_file_iterative(base_folder, FILE_SEARCH, stop_folder_name) if stop_folder_name == "to" or stop_folder_name is None: assert ret is not None assert ret.name == FILE_SEARCH @@ -196,12 +221,12 @@ def test_search_file_iterative(base_folder, target_file_pth, stop_folder_name): def test_search_folder_path(base_folder): stop_folder = "123" # should not exist - found = paths.search_folder_path(base_folder, stop_folder_name=stop_folder) + found = io.search_folder_path(base_folder, stop_folder_name=stop_folder) assert found is None stop_folder = "to" - found = paths.search_folder_path(base_folder, stop_folder_name=stop_folder) + found = io.search_folder_path(base_folder, stop_folder_name=stop_folder) assert found is not None assert found.name == "path" stop_folder = None - found = paths.search_folder_path(base_folder, stop_folder_name=stop_folder) + found = io.search_folder_path(base_folder, stop_folder_name=stop_folder) assert found is None