Source code for thesis.core.utils.utils
"""Core utility functions for path and config handling."""
import os
from pathlib import Path
from typing import Iterable, Optional, Union, overload
__all__ = [
"to_path",
"resolve_path",
"write_list_file",
]
@overload
def to_path(v: None) -> None: ...
@overload
def to_path(v: Union[str, Path]) -> Path: ...
[docs]
def to_path(v: Union[str, Path, None]) -> Optional[Path]:
"""
Convert a string or Path to a Path object, expanding ~ and environment variables.
Args:
v: Path value as string, Path, or None
Returns:
Expanded Path object, or None if input was None
"""
if v is None:
return None
return Path(os.path.expandvars(os.path.expanduser(str(v))))
[docs]
def resolve_path(base: Path, value: Union[Path, str]) -> Path:
"""
Resolve a path relative to a base directory, expanding ~ and environment variables.
Args:
base: Base directory for relative paths
value: Path to resolve (absolute or relative)
Returns:
Resolved Path object. If value is absolute, returns it expanded.
Otherwise, returns base / expanded_value.
"""
p = to_path(value)
if p is None:
raise ValueError("Cannot resolve None path")
if p.is_absolute():
return p
return (base / p).resolve()
[docs]
def write_list_file(paths: Iterable[Path], out_file: Path) -> Path:
"""
Write a list of paths to a text file, one per line.
Args:
paths: Iterable of Path objects to write
out_file: Output file path
Returns:
Path to the written file
"""
out_file.parent.mkdir(parents=True, exist_ok=True)
with out_file.open("w", encoding="utf-8") as f:
for p in paths:
f.write(str(p) + "\n")
return out_file