diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 39fb3c49..f90e1721 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,20 +21,20 @@ jobs: strategy: fail-fast: false matrix: - os: ['macos-14', 'macos-latest', 'ubuntu-latest', 'windows-latest'] - python-version: ['3.12', '3.13', '3.14'] + os: ['macos-latest', 'ubuntu-latest', 'windows-latest'] + python-version: ['3.12', '3.13', '3.14', '3.14t'] steps: - name: Set up the repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: submodules: recursive fetch-depth: 0 - name: Setup Python ${{ matrix.python-version }} - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: ${{ matrix.python-version }} - name: Setup uv - uses: astral-sh/setup-uv@v6 + uses: astral-sh/setup-uv@v7 - name: Build run: | uv sync --frozen --inexact -v --no-install-project diff --git a/.github/workflows/dist.yml b/.github/workflows/dist.yml index 0ede702c..40612bab 100644 --- a/.github/workflows/dist.yml +++ b/.github/workflows/dist.yml @@ -15,8 +15,8 @@ jobs: name: Build sdist runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: astral-sh/setup-uv@v6 + - uses: actions/checkout@v6 + - uses: astral-sh/setup-uv@v7.4.0 - name: Build sdist run: uv build --sdist - uses: actions/upload-artifact@v4 @@ -35,12 +35,15 @@ jobs: - windows-latest - windows-11-arm - macos-latest + - ubuntu-24.04-arm + - macos-15-intel + steps: - - uses: actions/checkout@v4 - - uses: astral-sh/setup-uv@v6 + - uses: actions/checkout@v6 + - uses: astral-sh/setup-uv@v7.4.0 - name: Build wheels - uses: pypa/cibuildwheel@v3.1 - - uses: actions/upload-artifact@v4 + uses: pypa/cibuildwheel@v3.4.0 + - uses: actions/upload-artifact@v7.0.0 with: name: release-wheels-${{ matrix.os }} path: wheelhouse/*.whl @@ -50,14 +53,13 @@ jobs: # https://github.com/pypa/gh-action-pypi-publish name: Upload wheels to PyPI needs: [build_wheels, make_sdist] - if: runs-on: ubuntu-latest permissions: id-token: write attestations: write contents: read steps: - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@v8.0.1 with: pattern: release-* path: dist @@ -67,7 +69,7 @@ jobs: run: ls -l -R dist - name: Generate artifact attestations - uses: actions/attest-build-provenance@v2 + uses: actions/attest-build-provenance@v4.1.0 if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags') with: subject-path: "dist/*" diff --git a/.github/workflows/flake.yml b/.github/workflows/flake.yml index e35f58f7..a03c1028 100644 --- a/.github/workflows/flake.yml +++ b/.github/workflows/flake.yml @@ -12,14 +12,14 @@ jobs: runs-on: [ubuntu-latest] steps: - name: Set up the repository - uses: actions/checkout@v2 + uses: actions/checkout@v6 with: submodules: recursive fetch-depth: 0 - name: Set up Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v6 with: - python-version: 3.8 + python-version: '3.12' - name: Install dependencies run: | python -m pip install --upgrade pip diff --git a/meson.build b/meson.build index 48016bb2..b3dc8d74 100644 --- a/meson.build +++ b/meson.build @@ -1,6 +1,10 @@ -project('cysignals', 'c', 'cpp', 'cython', - version: '1.12.6', - default_options: ['warning_level=2', 'cpp_std=c++17'] +project( + 'cysignals', + 'c', + 'cpp', + 'cython', + version: '1.12.6', + default_options: ['warning_level=2', 'cpp_std=c++17'], ) # Python @@ -15,7 +19,7 @@ cxx = meson.get_compiler('cpp') is_windows = host_machine.system() == 'windows' is_cygwin = host_machine.system() == 'cygwin' is_msvc = cc.get_id() == 'msvc' -is_mingw = cc.get_id()=='gcc' and host_machine.system()=='windows' +is_mingw = cc.get_id() == 'gcc' and host_machine.system() == 'windows' # Set preprocessor macros # Disable .c line numbers in exception tracebacks @@ -23,9 +27,9 @@ add_project_arguments('-DCYTHON_CLINE_IN_TRACEBACK=0', language: 'c') # Platform-specific settings if is_cygwin - # On Cygwin FD_SETSIZE defaults to a rather low 64; we set it higher for use with PSelecter - # See https://github.com/sagemath/cysignals/pull/57 - add_project_arguments('-DFD_SETSIZE=512', language: 'c') + # On Cygwin FD_SETSIZE defaults to a rather low 64; we set it higher for use with PSelecter + # See https://github.com/sagemath/cysignals/pull/57 + add_project_arguments('-DFD_SETSIZE=512', language: 'c') endif config = configuration_data() @@ -47,10 +51,14 @@ config.set('HAVE_BACKTRACE', cc.has_function('backtrace') ? 1 : 0) # We add the "leal" instruction to reduce false positives in case some # non-x86 architecture also has an "emms" instruction. -config.set('HAVE_EMMS', cc.links('int main() { asm("leal (%eax), %eax; emms"); return 0; }') ? 1 : 0) +config.set( + 'HAVE_EMMS', + cc.links('int main() { asm("leal (%eax), %eax; emms"); return 0; }') ? 1 : 0, +) # Whether setjmp() saves the signal mask -setjmp_saves_mask = cc.links(''' +setjmp_saves_mask = cc.links( + ''' #include #include #include @@ -67,49 +75,94 @@ int main() { if (sigprocmask(SIG_SETMASK, NULL, &set)) return 4; return sigismember(&set, SIGFPE); } -''') -gnulibc = cc.links(''' +''', +) +gnulibc = cc.links( + ''' #include #ifndef __GLIBC__ syntax error! #endif int main() { return 0; } -''') +''', +) # Define to 1 to use sigsetjmp() in sig_on(), as opposed to setjmp(). config.set('CYSIGNALS_USE_SIGSETJMP', (setjmp_saves_mask or gnulibc) ? 1 : 0) # Check for atomic operations # for _Atomic in C code -config.set('CYSIGNALS_C_ATOMIC', cc.links('int main(void) { static _Atomic int x; return 0; }') ? 1 : 0) +config.set( + 'CYSIGNALS_C_ATOMIC', + cc.links('int main(void) { static _Atomic int x; return 0; }') ? 1 : 0, +) # for _Atomic with OpenMP in C code -config.set('CYSIGNALS_C_ATOMIC_WITH_OPENMP', cc.links('int main(void) { static _Atomic int x; return 0; }', args: ['-fopenmp']) ? 1 : 0) +config.set( + 'CYSIGNALS_C_ATOMIC_WITH_OPENMP', + cc.links( + 'int main(void) { static _Atomic int x; return 0; }', + args: ['-fopenmp'], + ) ? 1 : 0, +) # for _Atomic in C++ code -config.set('CYSIGNALS_CXX_ATOMIC', cxx.links('int main() { static _Atomic int x; return 0; }') ? 1 : 0) +config.set( + 'CYSIGNALS_CXX_ATOMIC', + cxx.links('int main() { static _Atomic int x; return 0; }') ? 1 : 0, +) # for _Atomic with OpenMP in C++ code -config.set('CYSIGNALS_CXX_ATOMIC_WITH_OPENMP', cxx.links('int main() { static _Atomic int x; return 0; }', args: ['-fopenmp']) ? 1 : 0) +config.set( + 'CYSIGNALS_CXX_ATOMIC_WITH_OPENMP', + cxx.links( + 'int main() { static _Atomic int x; return 0; }', + args: ['-fopenmp'], + ) ? 1 : 0, +) # for std::atomic in C++ code -config.set('CYSIGNALS_STD_ATOMIC', cxx.links('#include \nint main() { static std::atomic x; return 0; }') ? 1 : 0) +config.set( + 'CYSIGNALS_STD_ATOMIC', + cxx.links( + '#include \nint main() { static std::atomic x; return 0; }', + ) ? 1 : 0, +) # for std::atomic with OpenMP in C++ code -config.set('CYSIGNALS_STD_ATOMIC_WITH_OPENMP', cxx.links('#include \nint main() { static std::atomic x; return 0; }', args: ['-fopenmp']) ? 1 : 0) +config.set( + 'CYSIGNALS_STD_ATOMIC_WITH_OPENMP', + cxx.links( + '#include \nint main() { static std::atomic x; return 0; }', + args: ['-fopenmp'], + ) ? 1 : 0, +) if is_windows - threads_dep = [] + threads_dep = [] else - threads_dep = dependency('threads') + threads_dep = dependency('threads') endif subdir('src') pytest = py_module.find_installation(modules: ['pytest'], required: false) if pytest.found() - test('pytest', pytest, args: ['-m', 'pytest'], workdir: meson.current_source_dir(), timeout: 300, verbose: true, is_parallel: false) + test( + 'pytest', + pytest, + args: ['-m', 'pytest'], + workdir: meson.current_source_dir(), + timeout: 300, + verbose: true, + is_parallel: false, + ) else - message('pytest not found, skipping tests') + message('pytest not found, skipping tests') endif build = py_module.find_installation(modules: ['build'], required: false) if build.found() - test('example', py, args: ['-m', 'build', '--no-isolation', 'example'], workdir: meson.current_source_dir()) + test( + 'example', + py, + args: ['-m', 'build', '--no-isolation', 'example'], + workdir: meson.current_source_dir(), + ) else - message('build not found, skipping example') + message('build not found, skipping example') endif diff --git a/pyproject.toml b/pyproject.toml index 2d702dfb..044d7f02 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -51,7 +51,8 @@ dev = [ ] [tool.cibuildwheel] -skip = ["*-win32"] +enable = ["cpython-freethreading"] +skip = ["*-win32", "cp313t-*"] test-groups = ["dev"] test-sources = ["tests", "pyproject.toml"] test-command = "python -m pytest" diff --git a/src/cysignals/meson.build b/src/cysignals/meson.build index ed2617a4..cfb71fb1 100644 --- a/src/cysignals/meson.build +++ b/src/cysignals/meson.build @@ -1,4 +1,20 @@ -configure_file(output: 'cysignals_config.h', configuration: config, install_dir: py.get_install_dir(pure: false) / 'cysignals', install: true) +pkgconf = configuration_data() +pkgconf.set('VERSION', meson.project_version()) + +configure_file( + output: 'cysignals_config.h', + configuration: config, + install_dir: py.get_install_dir(pure: false) / 'cysignals', + install: true, +) + +configure_file( + input: 'cysignals.pc.in', + output: 'cysignals.pc', + configuration: pkgconf, + install_dir: py.get_install_dir(pure: false) / 'cysignals', + install: true, +) pc_config = configuration_data() pc_config.set('VERSION', meson.project_version()) @@ -12,7 +28,7 @@ py.install_sources( 'signals.pxd', 'struct_signals.h', 'macros.h', - subdir: 'cysignals' + subdir: 'cysignals', ) extensions = { @@ -29,7 +45,8 @@ foreach name, pyx : extensions continue endif - py.extension_module(name, + py.extension_module( + name, pyx, include_directories: [include_directories('.'), src], cython_args: ['-Wextra'], diff --git a/src/scripts/meson.build b/src/scripts/meson.build index 0b8b175d..a652fcc9 100644 --- a/src/scripts/meson.build +++ b/src/scripts/meson.build @@ -1,2 +1,2 @@ -install_data('cysignals-CSI', install_dir : get_option('bindir')) +install_data('cysignals-CSI', install_dir: get_option('bindir'))