Skip to content

Modernize pyalps build (standalone nanobind wheel build) - #107

Draft
skilledwolf wants to merge 8 commits into
masterfrom
modernization/pyalps-nanobind-wheel
Draft

Modernize pyalps build (standalone nanobind wheel build)#107
skilledwolf wants to merge 8 commits into
masterfrom
modernization/pyalps-nanobind-wheel

Conversation

@skilledwolf

Copy link
Copy Markdown
Collaborator

Summary

This PR addresses the Python-package portion of #86. It replaces the
Boost.Python extension modules with nanobind and makes pyalps an independently
buildable scikit-build-core project under bindings/python/pyalps.

The intent is to remove the legacy Python build as a constraint on later ALPS
CMake modernization while preserving the existing Python module surface.

What changes

  • translate all 17 existing extension targets from Boost.Python to nanobind
  • add a standalone scikit-build-core build for wheels and source distributions
  • move Python packaging metadata and documentation next to the Python project
  • package the canonical repository LICENSE.txt in wheels and sdists
  • remove obsolete Python-only paths, options, and no-op flags from the main
    CMake build
  • build wheels for CPython 3.10 through 3.14
  • retain both macOS 15 and macOS 26 wheel publication coverage
  • update pyalps for current Python, NumPy, and SciPy:
    • replace removed top-level SciPy numerical APIs with NumPy
    • remove remaining Python 2 compatibility paths
    • fix Python 3 iterator behavior and NumPy array comparisons
    • use collections.abc
    • make Matplotlib an optional plot extra and avoid importing it during
      package initialization
  • declare runtime dependencies in pyproject.toml and remove the obsolete root
    requirements.txt
  • add binding-surface and compatibility tests

The declared baseline is Python >= 3.10, NumPy >= 1.26, and SciPy >= 1.13.

Review guide

The commits are intentionally separated by concern and are best reviewed in
order:

  1. feat: migrate pyalps bindings to nanobind

    This is the large, predominantly mechanical binding translation. The main
    review questions are whether classes, functions, overloads, conversions, and
    ownership/reference policies are represented correctly. It deliberately
    avoids general C++ API cleanup.

  2. build: retire legacy Python CMake paths

    This removes Python-only options and build machinery that no longer have a
    consumer after the standalone package is introduced.

  3. build: relocate pyalps project metadata and
    build: retain macos 26 wheel coverage

    These cover project layout, distribution metadata, canonical license
    inclusion, and the wheel matrix. The small follow-up commit preserves macOS
    26 and avoids physically duplicating the license.

  4. fix: modernize pyalps Python compatibility

    This is a focused Python 3 and NumPy/SciPy compatibility pass, independent of
    the C++ binding syntax.

Reviewers do not need to cover every area: C++/nanobind semantics, CMake and
packaging, and Python compatibility can be reviewed independently.

Binding coverage

The previous CMake build and the new standalone build both declare these 17
extension modules:

pyalea_c, pymcdata_c, pytools_c, pyngsparams_c, pyngshdf5_c,
pyngsbase_c, pyngsobservable_c, pyngsobservables_c, pyngsresult_c,
pyngsresults_c, pyngsapi_c, pyngsrandom01_c, pyngsaccumulator_c,
maxent_c, cthyb, ctint, and dwa_c.

Area Before After Expected user impact
Binding layer Boost.Python nanobind Existing Python API retained
Python build Main ALPS CMake tree Standalone scikit-build-core project Wheels can be built independently
Python support Legacy/implicit Python 3.10-3.14 Explicit supported range
Numerical dependencies Stale root pins pyproject.toml metadata Current NumPy/SciPy supported
Plotting Imported eagerly Optional plot extra Core imports do not require Matplotlib
License Packaging-dependent Canonical root license included License reliably ships in distributions

Validation

Local validation on macOS arm64 includes:

  • builds with ccache using both an Apple Clang MPI-enabled ALPS SDK and a
    Homebrew LLVM non-MPI SDK
  • a complete CPython 3.13 wheel containing all 17 extension modules
  • NumPy 2.3.5 and SciPy 1.17.0
  • all 14 pyalps tests passing with deprecation warnings treated as errors
  • imports of pyalps and pyalps.dwa with Matplotlib unavailable
  • successful wheel and source-distribution metadata inspection
  • verification that the wheel contains the canonical ALPS license

CI exercises the CPython 3.10-3.14 wheel matrix and the supported macOS
deployment targets.

Scope and follow-up work

This PR deliberately does not attempt:

  • broader target-based CMake modernization
  • Spack recipe changes
  • general C++ API cleanup
  • mass Python formatting or style modernization
  • redesign of old pyalps APIs
  • MPI wheel/package redesign

Those changes should be easier to review once the legacy Python build no longer
constrains the main build.

Closes the Python packaging portion of #86; it does not close the overall issue.

@skilledwolf

Copy link
Copy Markdown
Collaborator Author

Apologies, I know this PR will be annoying to review, but I didn't see a way to land this in smaller units.

Please let me know what you think, and whether the implicit decisions are reasonable / compatible with your long term vision, I'm happy to make any changes!

skilledwolf and others added 2 commits July 22, 2026 15:51
CIBW_ENVIRONMENT does not expand the {project} placeholder (only
before-all/before-build/test/repair commands do), so ALPS_DIR and
CCACHE_DIR were set to the literal string "{project}/...". The wheel
build's find_package(ALPS REQUIRED CONFIG) then could not locate the
ALPSConfig.cmake installed by CIBW_BEFORE_ALL, failing CMake configure.

Use $(pwd), which cibuildwheel evaluates in the build environment
(cwd=/project in the Linux container, repo root on macOS) to the same
directory where _build/cibw-install lives. Validated end-to-end with a
local manylinux_2_28_aarch64 build: wheel builds, repairs, 14 tests pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
musllinux (Alpine/musl) lacks dnf, glibc's SunRPC/XDR, and execinfo.
Branch before_all to apk; install libtirpc for ALPS's system-XDR path
(ALPS_HAVE_RPC_XDR_H) and disable the execinfo backtrace. Validated
end-to-end on musllinux_1_2_aarch64: wheel builds, auditwheel bundles
libtirpc, 14/14 tests pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@skilledwolf skilledwolf mentioned this pull request Jul 23, 2026
@skilledwolf skilledwolf changed the title Modernize pyalps bindings and add a standalone nanobind wheel build Modernize pyalps build (standalone nanobind wheel build) Jul 23, 2026
@skilledwolf skilledwolf added the enhancement New feature or request label Jul 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant