Skip to content

Commit

Permalink
✨Allowed inferring of format 'folder' for 'save_result'
Browse files Browse the repository at this point in the history
Added tests for folder plugin where result_path is an existing file without an extension.
  • Loading branch information
s-weigand committed Mar 29, 2021
1 parent 2f6d9ce commit 4c55102
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 14 deletions.
6 changes: 3 additions & 3 deletions glotaran/builtin/io/folder/folder_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,13 @@ def save_result(self, result_path: str, result: Result) -> list[str]:
Raises
------
OSError
ValueError
If the folder to save the result in doesn't exist or couldn't be created.
"""
if not os.path.exists(result_path):
os.makedirs(result_path)
elif not os.path.isdir(result_path):
raise OSError(f"The path '{result_path}' is not a directory.")
if not os.path.isdir(result_path):
raise ValueError(f"The path '{result_path}' is not a directory.")

paths = []

Expand Down
37 changes: 32 additions & 5 deletions glotaran/builtin/io/folder/test/test_folder_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,18 @@
from glotaran.analysis.test.models import ThreeDatasetDecay as suite
from glotaran.io import save_result
from glotaran.project import Scheme
from glotaran.project.result import Result

if TYPE_CHECKING:
from typing import Literal

from py.path import local as TmpDir


@pytest.mark.parametrize("format_names", ("folder", "pyglotaran-legacy"))
def test_save_result_folder(tmpdir: TmpDir, format_name: Literal["folder", "pyglotaran-legacy"]):
"""Check all files exist."""
@pytest.fixture(scope="module")
def dummy_result():
"""Dummy result for testing."""

model = suite.model

model.is_grouped = False
Expand All @@ -41,13 +43,38 @@ def test_save_result_folder(tmpdir: TmpDir, format_name: Literal["folder", "pygl
maximum_number_function_evaluations=1,
)

result = optimize(scheme)
yield optimize(scheme)


@pytest.mark.parametrize("format_name", ("folder", "pyglotaran-legacy"))
def test_save_result_folder(
tmpdir: TmpDir, dummy_result: Result, format_name: Literal["folder", "pyglotaran-legacy"]
):
"""Check all files exist."""

result_dir = Path(tmpdir / "testresult")
save_result(result_path=str(result_dir), format_name=format_name, result=result)
save_result(result_path=str(result_dir), format_name=format_name, result=dummy_result)

assert (result_dir / "result.md").exists()
assert (result_dir / "optimized_parameters.csv").exists()
assert (result_dir / "dataset1.nc").exists()
assert (result_dir / "dataset2.nc").exists()
assert (result_dir / "dataset3.nc").exists()


@pytest.mark.parametrize("format_name", ("folder", "pyglotaran-legacy"))
def test_save_result_folder_error_path_is_file(
tmpdir: TmpDir, dummy_result: Result, format_name: Literal["folder", "pyglotaran-legacy"]
):
"""Raise error if result_path is a file without extension and overwrite is true."""

result_dir = Path(tmpdir / "testresult")
result_dir.touch()

with pytest.raises(ValueError, match="The path '.+?' is not a directory."):
save_result(
result_path=str(result_dir),
format_name=format_name,
result=dummy_result,
allow_overwrite=True,
)
19 changes: 14 additions & 5 deletions glotaran/plugin_system/io_plugin_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
DecoratedFunc = TypeVar("DecoratedFunc", bound=Callable[..., Any]) # decorated function


def inferr_file_format(file_path: str | os.PathLike[str], *, needs_to_exist: bool = True) -> str:
def inferr_file_format(
file_path: str | os.PathLike[str], *, needs_to_exist: bool = True, allow_folder=False
) -> str:
"""Inferr format of a file if it exists.
Parameters
Expand All @@ -25,6 +27,9 @@ def inferr_file_format(file_path: str | os.PathLike[str], *, needs_to_exist: boo
needs_to_exist : bool
Whether or not a file need to exists for an successful format inferring.
While write functions don't need the file to exists, load functions do.
allow_folder: bool
Whether or not to allow the format to be ``folder``.
This is only used in ``save_result``.
Returns
-------
Expand All @@ -38,14 +43,18 @@ def inferr_file_format(file_path: str | os.PathLike[str], *, needs_to_exist: boo
ValueError
If file has no extension.
"""
if not os.path.isfile(file_path) and needs_to_exist:
if not os.path.isfile(file_path) and needs_to_exist and not allow_folder:
raise ValueError(f"There is no file {file_path!r}.")

_, file_format = os.path.splitext(file_path)
if file_format == "":
raise ValueError(
f"Cannot determine format of file {file_path!r}, please provide an explicit format."
)
if allow_folder:
return "folder"
else:
raise ValueError(
f"Cannot determine format of file {file_path!r}, "
"please provide an explicit format."
)
else:
return file_format.lstrip(".")

Expand Down
4 changes: 3 additions & 1 deletion glotaran/plugin_system/project_io_registration.py
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,9 @@ def save_result(
of the project io plugin.
"""
protect_from_overwrite(result_path, allow_overwrite=allow_overwrite)
io = get_project_io(format_name or inferr_file_format(result_path, needs_to_exist=False))
io = get_project_io(
format_name or inferr_file_format(result_path, needs_to_exist=False, allow_folder=True)
)
io.save_result( # type: ignore[call-arg]
result_path=result_path,
result=result,
Expand Down
10 changes: 10 additions & 0 deletions glotaran/plugin_system/test/test_io_plugin_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,16 @@ def test_inferr_file_format_no_extension(tmp_path: Path):
inferr_file_format(file_path)


@pytest.mark.parametrize("is_file", (True, False))
def test_inferr_file_format_allow_folder(tmp_path: Path, is_file: bool):
"""If there is no extension, return folder."""
file_path = tmp_path / "dummy"
if is_file:
file_path.touch()

assert inferr_file_format(file_path, allow_folder=True) == "folder"


def test_inferr_file_format_none_existing_file():
"""Raise error if file does not exists."""
with pytest.raises(ValueError, match="There is no file "):
Expand Down

0 comments on commit 4c55102

Please sign in to comment.