Source code for symforce.path_util

# ----------------------------------------------------------------------------
# SymForce - Copyright 2022, Skydio, Inc.
# This source code is under the Apache 2.0 license found in the LICENSE file.
# ----------------------------------------------------------------------------

import json
import os
import typing as T
from pathlib import Path


[docs]class MissingManifestException(RuntimeError): pass
class _Manifest: """ Internal class to manage loading data from the build manifest and caching that data. Not intended for use outside of path_util.py. """ _manifest: T.Optional[T.Dict[str, str]] = None @classmethod def _ensure_loaded(cls) -> None: if cls._manifest is None: manifest_path = Path(__file__).parent.parent / "build" / "manifest.json" try: with open(manifest_path) as f: cls._manifest = json.load(f) except FileNotFoundError as ex: raise MissingManifestException(f"Manifest not found at {manifest_path}") from ex @classmethod def get_entry(cls, key: str) -> Path: cls._ensure_loaded() assert cls._manifest is not None return Path(cls._manifest[key]).resolve() @classmethod def get_entries(cls, key: str) -> T.List[Path]: cls._ensure_loaded() assert cls._manifest is not None return [Path(s).resolve() for s in cls._manifest[key]]
[docs]def symforce_dir() -> Path: return Path(__file__).parent.parent
[docs]def symenginepy_install_dir() -> Path: return _Manifest.get_entry("symenginepy_install_dir")
[docs]def cc_sym_install_dir() -> Path: return _Manifest.get_entry("cc_sym_install_dir")
[docs]def binary_output_dir() -> Path: return _Manifest.get_entry("binary_output_dir")
[docs]def symforce_root() -> Path: """ The root directory of the symforce project """ return Path(__file__).parent.parent
[docs]def symforce_data_root(test_file_path: T.Optional[str]) -> Path: """ The root directory of the symforce project, for use accessing data that might need to be updated (such as generated files). Most of the time this is the same as :func:`symforce_root`, except for two cases: 1) When running tests on wheels, this is the root of the copy of SymForce containing the test, not the installed copy. The generated files we're checking aren't in the wheel, they're in the source tree. 2) When the ``--update`` flag is passed to a test, this is guaranteed to point to the *resolved* version, i.e. the actual symforce location on disk regardless of whether this path is a symlink. """ from symforce.test_util.test_case_mixin import SymforceTestCaseMixin if test_file_path is not None and "SYMFORCE_WHEEL_TESTS" in os.environ: return Path(test_file_path).resolve().parent.parent if SymforceTestCaseMixin.should_update(): return Path(__file__).resolve().parent.parent else: return symforce_root()