Skip to content
Open
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
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