From ab08e019c7ed49558dc9c85989bce514ebcbeecf Mon Sep 17 00:00:00 2001 From: iopapamanoglou Date: Tue, 29 Oct 2024 15:13:32 +0100 Subject: [PATCH] cleanup init --- src/faebryk/core/cpp/__init__.py | 56 ++++++++++++++++++-------------- src/faebryk/libs/header.py | 7 ++++ src/faebryk/libs/util.py | 4 +-- 3 files changed, 41 insertions(+), 26 deletions(-) diff --git a/src/faebryk/core/cpp/__init__.py b/src/faebryk/core/cpp/__init__.py index 42a1a9f0..8b5525f1 100644 --- a/src/faebryk/core/cpp/__init__.py +++ b/src/faebryk/core/cpp/__init__.py @@ -3,19 +3,10 @@ import json import logging -import shutil from importlib.metadata import Distribution -from pathlib import Path - -from faebryk.libs.header import get_header logger = logging.getLogger(__name__) -_thisfile = Path(__file__) -_thisdir = _thisfile.parent -_cmake_dir = _thisdir -_build_dir = _cmake_dir / "build" - # Check if installed as editable def is_editable_install(): @@ -32,11 +23,24 @@ def compile_and_load(): Forces C++ to compile into faebryk_core_cpp_editable module which is then loaded into _cpp. """ + import os import platform + import shutil import sys + from pathlib import Path + from faebryk.libs.header import formatted_file_contents, get_header from faebryk.libs.util import run_live + _thisfile = Path(__file__) + _thisdir = _thisfile.parent + _cmake_dir = _thisdir + _build_dir = _cmake_dir / "build" + pyi_source = _build_dir / "faebryk_core_cpp_editable.pyi" + + date_files = [pyi_source] + dates = {k: os.path.getmtime(k) if k.exists() else 0 for k in date_files} + # check for cmake binary existing if not shutil.which("cmake"): raise RuntimeError( @@ -63,8 +67,8 @@ def compile_and_load(): str(_build_dir), "-DEDITABLE=1", "-DPython_EXECUTABLE=" + sys.executable, - ] - + other_flags, + *other_flags, + ], logger=logger, ) run_live( @@ -79,26 +83,30 @@ def compile_and_load(): if not _build_dir.exists(): raise RuntimeError("build directory not found") + # add build dir to sys path sys.path.append(str(_build_dir)) + modified = {k for k, v in dates.items() if os.path.getmtime(k) > v} + + # move autogenerated type stub file to source directory + if pyi_source in modified: + pyi_out = _thisfile.with_suffix(".pyi") + pyi_out.write_text( + formatted_file_contents( + get_header() + + "\n" + + "# This file is auto-generated by nanobind.\n" + + "# Do not edit this file directly; edit the corresponding\n" + + "# C++ file instead.\n\n" + + pyi_source.read_text() + ) + ) + # Re-export c++ with type hints provided by __init__.pyi if is_editable_install(): logger.warning("faebryk is installed as editable package, compiling c++ code") compile_and_load() from faebryk_core_cpp_editable import * # type: ignore # noqa: E402, F403 - - # move autogenerated type stub file to source directory - pyi_file = _build_dir / "faebryk_core_cpp_editable.pyi" - pyi_out = _thisfile.with_suffix(".pyi") - pyi_out.write_text( - get_header() - + "\n" - + "# This file is auto-generated by nanobind.\n" - + "# Do not edit this file directly; edit the corresponding\n" - + "# C++ file instead.\n" - + pyi_file.read_text() - ) - else: from faebryk_core_cpp import * # type: ignore # noqa: E402, F403 diff --git a/src/faebryk/libs/header.py b/src/faebryk/libs/header.py index 7ba4eeb8..b907a9a8 100644 --- a/src/faebryk/libs/header.py +++ b/src/faebryk/libs/header.py @@ -2,8 +2,15 @@ # SPDX-License-Identifier: MIT +import black + + def get_header(): return ( "# This file is part of the faebryk project\n" "# SPDX-License-Identifier: MIT\n" ) + + +def formatted_file_contents(file_contents: str) -> str: + return black.format_str(file_contents, mode=black.Mode()) diff --git a/src/faebryk/libs/util.py b/src/faebryk/libs/util.py index e15c15a5..e6a44653 100644 --- a/src/faebryk/libs/util.py +++ b/src/faebryk/libs/util.py @@ -1092,7 +1092,7 @@ def run_live( stdout_level: int | None = logging.DEBUG, stderr_level: int | None = logging.ERROR, **kwargs, -) -> str: +) -> tuple[str, subprocess.Popen]: """Runs a process and logs the output live.""" process = subprocess.Popen( @@ -1134,4 +1134,4 @@ def run_live( process.returncode, args[0], "".join(stdout) ) - return "\n".join(stdout) + return "\n".join(stdout), process