diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0c6fdd2..4e1e3e5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,6 +9,10 @@ on: schedule: - cron: '17 3 * * 0' +concurrency: + group: ${{ github.head_ref || github.ref_name }} + cancel-in-progress: true + jobs: ruff: name: Ruff @@ -33,12 +37,28 @@ jobs: uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} + - uses: MarkusJx/install-boost@v2 + with: + boost_version: 1.87.0 + boost_install_dir: /home/runner/boost + id: install-boost - name: "Main Script" + env: + BOOST_ROOT: ${{ steps.install-boost.outputs.BOOST_ROOT }} run: | curl -L -O https://tiker.net/ci-support-v0 . ./ci-support-v0 + PY_VER=$(python3 -c 'import sys; print(f"{sys.version_info[0]}{sys.version_info[1]}")') + cat > $HOME/.aksetup-defaults.py < None: """Using *toolchain*, build the extension file named *ext_file* from the source code in *source_string*, which is saved to a - temporary file named *source_name*. Raise :exc:`CompileError` in + temporary file named *source_name*. Raise :exc:`~codepy.CompileError` in case of error. If *debug* is True, show commands involved in the build. @@ -195,12 +200,11 @@ def extension_from_string( source_name: str | list[str] = "module.cpp", cache_dir: str | None = None, debug: bool = False, - wait_on_error: bool | None = None, debug_recompile: bool = True, sleep_delay: int = 1) -> ModuleType: """Return a reference to the extension module *name*, which can be built from the source code in *source_string* if necessary. Raise - :exc:`CompileError` in case of error. + :exc:`codepy.CompileError` in case of error. Compiled code is cached in *cache_dir* and available immediately if it has been compiled at some point in the past. Compiler and Python API versions @@ -221,8 +225,9 @@ def extension_from_string( recompilation is taking place. """ _checksum, mod_name, ext_file, _recompiled = ( - compile_from_string(toolchain, name, source_string, source_name, - cache_dir, debug, wait_on_error, debug_recompile, + compile_from_string(toolchain, name, source_string, source_name=source_name, + cache_dir=cache_dir, debug=debug, + debug_recompile=debug_recompile, object=False, sleep_delay=sleep_delay)) # try loading it @@ -250,10 +255,10 @@ def compile_from_string( toolchain: Toolchain, name: str, source_string: str | bytes | list[str] | list[bytes], + *, source_name: str | list[str] | None = None, cache_dir: str | None = None, debug: bool = False, - wait_on_error: bool | None = None, debug_recompile: bool = True, object: bool = False, source_is_binary: bool = False, @@ -265,7 +270,7 @@ def compile_from_string( *recompiled* is *True* if the object had to be recompiled, *False* if the cache is hit. - Raises :exc:`CompileError` in case of error. The *mod_name* and *file_name* + Raises :exc:`~codepy.CompileError` in case of error. The *mod_name* and *file_name* are designed to be used with ``load_dynamic`` to load a Python module from this object, if desired. @@ -306,11 +311,6 @@ def compile_from_string( if isinstance(source_name, str): source_name = [source_name] - if wait_on_error is not None: - from warnings import warn - warn("Passing 'wait_on_error' is deprecated and has no effect. ", - DeprecationWarning, stacklevel=2) - import os if cache_dir is None: @@ -487,7 +487,7 @@ def link_extension( mod_name: str, cache_dir: str | None = None, debug: bool = False, - wait_on_error: bool = True) -> ModuleType: + ) -> ModuleType: if not isinstance(toolchain, GCCLikeToolchain): raise TypeError(f"Unsupported toolchain type: {type(toolchain)}") @@ -501,12 +501,7 @@ def link_extension( destination_base, mod_name + toolchain.so_ext) - try: - toolchain.link_extension(destination, objects, debug=debug) - except CompileError: - if wait_on_error: - input(f"Link error, examine {objects}, then press [Enter]") - raise + toolchain.link_extension(destination, objects, debug=debug) # try loading it from codepy.tools import load_dynamic diff --git a/codepy/libraries.py b/codepy/libraries.py index b8f1176..42364b5 100644 --- a/codepy/libraries.py +++ b/codepy/libraries.py @@ -117,7 +117,12 @@ def update_config(fname: str) -> None: def get_boost_libname(basename: str, aksetup: Config) -> list[str]: varname = f"BOOST_{basename.upper()}_LIBNAME" - libs = getlist(aksetup, varname, [f"boost_{basename}"]) + default = f"boost_{basename}" + if basename == "python": + import sys + version = sys.version_info[:2] + default = "boost_python{}{}".format(*version) + libs = getlist(aksetup, varname, [default]) return libs @@ -133,7 +138,7 @@ def add_boost_python(toolchain: Toolchain) -> None: getlist(aksetup, "BOOST_INC_DIR", []), getlist(aksetup, "BOOST_LIB_DIR", []), [ - *get_boost_libname("python{}{}".format(*version), aksetup), + *get_boost_libname("python", aksetup), "python{}.{}{}".format(*version, sys.abiflags), ]) diff --git a/codepy/toolchain.py b/codepy/toolchain.py index c11370a..29aafb3 100644 --- a/codepy/toolchain.py +++ b/codepy/toolchain.py @@ -1,4 +1,22 @@ -"""Toolchains for Just-in-time Python extension compilation.""" +""" +:mod:`codepy.toolchain` -- Tool support code +-------------------------------------------- + +.. autoexception:: ToolchainGuessError + +.. autoclass:: Toolchain + :members: copy, get_version, abi_id, add_library, build_extension + :undoc-members: + +.. autoclass:: GCCLikeToolchain + :show-inheritance: + +.. autoclass:: GCCToolchain + :show-inheritance: + +.. autofunction:: guess_toolchain + +""" __copyright__ = """ "Copyright (C) 2008,9 Andreas Kloeckner, Bryan Catanzaro @@ -108,7 +126,7 @@ def build_extension(self, source_files: list[str], debug: bool = False) -> None: """Create the extension file *ext_file* from *source_files* - by invoking the toolchain. Raise :exc:`~codepy.jit.CompileError` in + by invoking the toolchain. Raise :exc:`~codepy.CompileError` in case of error. If *debug* is True, print the commands executed. diff --git a/doc/index.rst b/doc/index.rst index 1c522cc..8c398ce 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -5,8 +5,6 @@ Welcome to CodePy's documentation! ================================== -.. module:: codepy - CodePy is a C metaprogramming toolkit for Python. It handles two aspects of metaprogramming: diff --git a/doc/jit.rst b/doc/jit.rst index 2de0f85..053d5a9 100644 --- a/doc/jit.rst +++ b/doc/jit.rst @@ -14,43 +14,4 @@ to determine a few configuration values, notably: For lack of better installation documentation at this moment, please see `this wiki page `_. -:mod:`codepy.jit` -- Compilation and Linking of C Source Code -------------------------------------------------------------- - -.. module:: codepy.jit - -.. autofunction:: extension_file_from_string -.. autofunction:: extension_from_string - -Errors -^^^^^^ - -.. autoexception:: CompileError - -:mod:`codepy.toolchain` -- Tool support code --------------------------------------------- - -.. module:: codepy.toolchain - -.. autoexception:: ToolchainGuessError - -.. autoclass:: Toolchain - :members: copy, get_version, abi_id, add_library, build_extension - :undoc-members: - -.. autoclass:: GCCLikeToolchain - :show-inheritance: - -.. autoclass:: GCCToolchain - :show-inheritance: - -.. autofunction:: guess_toolchain - -:mod:`codepy.bpl` -- Support for Boost.Python ---------------------------------------------- - -.. automodule:: codepy.bpl - -.. autoclass:: BoostPythonModule - :members: - :undoc-members: +.. automodule:: codepy diff --git a/test/test_identical_symbols.py b/test/test_identical_symbols.py index a6b0eee..9b1669b 100644 --- a/test/test_identical_symbols.py +++ b/test/test_identical_symbols.py @@ -1,7 +1,5 @@ from types import ModuleType -import pytest - def make_greet_mod(greeting: str) -> ModuleType: from cgen import ( @@ -25,12 +23,9 @@ def make_greet_mod(greeting: str) -> ModuleType: )) from codepy.toolchain import guess_toolchain - return mod.compile(guess_toolchain(), wait_on_error=True) + return mod.compile(guess_toolchain()) -@pytest.mark.xfail(reason="You probably don't have " - "Boost.Python installed where I am looking for it, " - "and that's OK.") def test_identical_symbols() -> None: us = make_greet_mod("Hi there") aussie = make_greet_mod("G'day")