Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ build-backend = 'setuptools.build_meta'

[project]
name = "ratapi"
version = "0.0.0.dev11"
version = "0.0.0.dev12"
description = "Python extension for the Reflectivity Analysis Toolbox (RAT)"
readme = "README.md"
requires-python = ">=3.10"
Expand Down
8 changes: 1 addition & 7 deletions ratapi/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -313,13 +313,7 @@ class CustomFile(RATModel):
filename: str = ""
function_name: str = ""
language: Languages = Languages.Python
path: pathlib.Path = pathlib.Path(".").resolve()

@field_validator("path")
@classmethod
def resolve_relative_paths(cls, path: pathlib.Path) -> pathlib.Path:
"""Return the absolute path of the given path."""
return path.resolve()
path: pathlib.Path = pathlib.Path(".")

def model_post_init(self, __context: Any) -> None:
"""Autogenerate the function name from the filename if not set.
Expand Down
10 changes: 8 additions & 2 deletions ratapi/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -956,12 +956,16 @@ def make_data_dict(item):
elif field == "custom_files":

def make_custom_file_dict(item):
return {
file_dict = {
"name": item.name,
"filename": item.filename,
"language": item.language,
"path": try_relative_to(item.path, filepath.parent),
}
if item.name != item.function_name:
file_dict["function_name"] = item.function_name

return file_dict

json_dict["custom_files"] = [make_custom_file_dict(file) for file in attr]

Expand Down Expand Up @@ -1062,7 +1066,9 @@ def try_relative_to(path: Path, relative_to: Path) -> str:
"""
path = Path(path)
relative_to = Path(relative_to)
if path.is_relative_to(relative_to):
if not path.is_absolute():
return str(path)
elif path.is_relative_to(relative_to):
return str(path.relative_to(relative_to))
else:
warnings.warn(
Expand Down
8 changes: 8 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -8537,3 +8537,11 @@ def absorption():
"""The project from the absorption example."""
project, _ = ratapi.examples.absorption()
return project


@pytest.fixture
def absorption_different_function():
"""The project from the absorption example with a function name different from filename."""
project, _ = ratapi.examples.absorption()
project.custom_files[0].function_name = "test_func"
return project
11 changes: 5 additions & 6 deletions tests/test_models.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
"""Test the pydantic models."""

import pathlib
import re
from collections.abc import Callable

Expand Down Expand Up @@ -101,11 +100,11 @@ def test_initialise_with_extra_fields(self, model: Callable, model_params: dict)
model(new_field=1, **model_params)


def test_custom_file_path_is_absolute() -> None:
"""If we use provide a relative path to the custom file model, it should be converted to an absolute path."""
relative_path = pathlib.Path("./relative_path")
custom_file = ratapi.models.CustomFile(path=relative_path)
assert custom_file.path.is_absolute()
# def test_custom_file_path_is_absolute() -> None:
# """If we use provide a relative path to the custom file model, it should be converted to an absolute path."""
# relative_path = pathlib.Path("./relative_path")
# custom_file = ratapi.models.CustomFile(path=relative_path)
# assert custom_file.path.is_absolute()


def test_data_eq() -> None:
Expand Down
20 changes: 11 additions & 9 deletions tests/test_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -1616,6 +1616,7 @@ def test_wrap_extend(test_project, class_list: str, model_type: str, field: str,
"domains_custom_layers",
"domains_custom_xy",
"absorption",
"absorption_different_function",
],
)
def test_save_load(project, request):
Expand All @@ -1637,24 +1638,25 @@ def test_save_load(project, request):
def test_relative_paths():
"""Test that ``try_relative_to`` correctly creates relative paths to subfolders."""

with tempfile.TemporaryDirectory() as tmp:
data_path = Path(tmp, "data/myfile.dat")
cur_path = Path(".").resolve()
data_path = cur_path / "data/myfile.dat"
assert Path(ratapi.project.try_relative_to(data_path, cur_path)) == Path("data/myfile.dat")

assert Path(ratapi.project.try_relative_to(data_path, tmp)) == Path("data/myfile.dat")
# relative path will be left relative.
data_path = "data/myfile.dat"
assert Path(ratapi.project.try_relative_to(data_path, cur_path)) == Path("data/myfile.dat")


def test_relative_paths_warning():
"""Test that we get a warning for trying to walk up paths."""

data_path = "/tmp/project/data/mydata.dat"
relative_path = "/tmp/project/project_path/myproj.dat"
cur_path = Path(".").resolve()
data_path = cur_path / "tmp/project/data/mydata.dat"
relative_path = cur_path / "tmp/project/project_path/myproj.dat"

with pytest.warns(
match="Could not write custom file path as relative to the project directory, "
"which means that it may not work on other devices. If you would like to share your project, "
"make sure your custom files are in a subfolder of the project save location.",
):
assert (
Path(ratapi.project.try_relative_to(data_path, relative_path))
== Path("/tmp/project/data/mydata.dat").resolve()
)
assert Path(ratapi.project.try_relative_to(data_path, relative_path)) == data_path