-
Notifications
You must be signed in to change notification settings - Fork 32
Expand file tree
/
Copy pathpath_utils.py
More file actions
26 lines (19 loc) · 952 Bytes
/
Copy pathpath_utils.py
File metadata and controls
26 lines (19 loc) · 952 Bytes
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
"""Filesystem boundary helpers for NanoSage output artifacts."""
from __future__ import annotations
from pathlib import Path
def safe_resolve_under(base_dir: str | Path, *parts: str | Path) -> Path:
"""
Resolve a path and assert it stays inside ``base_dir``.
``base_dir`` itself may be absolute or relative. All joined child paths must
remain contained under that resolved base directory.
"""
base = Path(base_dir).expanduser().resolve()
candidate = base.joinpath(*map(Path, parts)).resolve()
if candidate != base and base not in candidate.parents:
raise ValueError(f"Refusing to write outside output root: {candidate}")
return candidate
def ensure_dir_under(base_dir: str | Path, *parts: str | Path) -> Path:
"""Create and return a directory that is guaranteed to live under base_dir."""
path = safe_resolve_under(base_dir, *parts)
path.mkdir(parents=True, exist_ok=True)
return path