""" core/paths.py ------------- Runtime path resolution that works both in development and when frozen by PyInstaller (--onefile or directory build). user_data_dir() — mutable data root (DB, exports) — next to the .exe bundled_asset(rel) — read-only asset path (icon etc.) — extracted bundle """ import os import sys def user_data_dir() -> str: """Root for mutable user data. Next to the .exe when frozen.""" if getattr(sys, "frozen", False): return os.path.dirname(sys.executable) # development: two levels up from core/paths.py → project root return os.path.dirname(os.path.dirname(os.path.abspath(__file__))) def bundled_asset(relative_path: str) -> str: """Absolute path to a read-only bundled asset (icon, etc.). In a onefile build sys._MEIPASS is the temp extraction dir; in a directory build it equals the exe directory. """ if getattr(sys, "frozen", False): base = sys._MEIPASS # type: ignore[attr-defined] else: base = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) return os.path.join(base, relative_path)