Skip to main content

Self-registering nanobind helpers (import as pymergetic.easybind)

Project description

easybind

Simple self-registering helpers for distributed nanobind bindings.

Install

pip install pymergetic-easybind

Platforms: PyPI ships manylinux (glibc 2.28+) and Windows amd64 wheels for CPython 3.11–3.14. macOS is not built in CI yet. On unsupported platforms pip may fall back to the sdist and require a local C++ toolchain.

import pymergetic.easybind
from pymergetic.easybind import sample  # optional demo module

PyPI project: pymergetic-easybind (install name). Import: pymergetic.easybind.

Version: Set by Git tags at build time (v0.1.0, …) via setuptools-scm; see RELEASING.md. At runtime, pymergetic.easybind._version.__version__ is written when the wheel is built (or use importlib.metadata.version("pymergetic-easybind")).

Local dev / clangd

An editable install configures CMake under ./build/ and generates build/compile_commands.json, which clangd picks up via .clangd — same database as the Python build, no second configure step:

uv pip install -e .    # or: pip install -e .

If you need compile_commands.json without pip, run scripts/clangd-update.sh (plain cmake -S . -B build …).

Python layer

The Python package is implemented as native extensions. It exposes:

  • pymergetic.easybind (core helpers and macros)
  • pymergetic.easybind.module (module tree API)
  • pymergetic.easybind.sample (demo bindings)

Build-time SDK

Installed wheels ship CMake helpers under pymergetic/easybind/cmake/:

  • easybind_pip.cmakeeasybind_pip_setup() finds Python, nanobind (pip), libeasybind, and include roots for #include <pymergetic/easybind/...>, then pulls in easybind_dependencies.cmake. Helpers: easybind_pip_link_magic_enum(target), easybind_pip_set_rpath_next_to_easybind(target easybind_pkg_dir).
  • easybind_dependencies.cmake — pins nanobind, magic_enum, reflect-cpp (same tags as this repo). Use easybind_fetch_third_party_deps() to pull all three, or easybind_fetch_nanobind() / easybind_fetch_magic_enum() / easybind_fetch_reflect_cpp() when you only need a subset (e.g. pip already provides nanobind, so call only easybind_fetch_magic_enum()).

Typical consumer bootstrap:

find_package(Python REQUIRED COMPONENTS Interpreter Development.Module)
execute_process(COMMAND "${Python_EXECUTABLE}" -c
  "import pathlib, pymergetic.easybind; print(pathlib.Path(pymergetic.easybind.__file__).resolve().parent / 'cmake' / 'easybind_pip.cmake')"
  OUTPUT_VARIABLE _eb_pip OUTPUT_STRIP_TRAILING_WHITESPACE COMMAND_ERROR_IS_FATAL ANY)
include("${_eb_pip}")
easybind_pip_setup()
easybind_fetch_magic_enum()   # if you include easybind headers that need magic_enum

When developing inside this repository, easybind_add_extension(...) is defined in the top-level CMakeLists.txt (not shipped in the wheel).

Devtools (release / pin bumps)

Implemented in pymergetic.common.devtools (pymergetic-common). Install via pymergetic-easybind (depends on common) or uv sync.

pymergetic-pin-pyproject --project-root packages/easybind --dry-run
pymergetic-release-tag --project-root packages/easybind --dry-run
pymergetic-wait-pypi --project-root packages/easybind

See pymergetic-common RELEASING.md and from pymergetic.common.devtools import ….

Core idea

  • Each namespace/module defines a ModuleNode and a bind callback.
  • The module entry point calls apply_init to run the callback and recurse.
  • Submodules are created on demand and registered in sys.modules.
  • Shared-object modules are marked so recursion stops at their boundary.
  • A minimal sample module lives at pymergetic.easybind.sample.

Developer note: layout rules

  • __init__.cpp marks the Python boundary (NB_MODULE) for a package/module.
  • node.cpp/.hpp is the pure C++ module-tree core.
  • ns_module.hpp defines the EASYBIND_NS_MODULE* macros.
  • Directory layout mirrors namespaces and Python modules.

Smallest possible example

1) Define a C++ type (normal code)

#pragma once

#include <string>

struct PeerInfo {
    std::string peer_id;
    int transport = 0;
};

2) Bind it in a separate file (module node)

#include <pymergetic/easybind/bind.hpp>

struct PeerInfo;  // forward declare or include the header

EASYBIND_NS_MODULE(my_pkg, m, false, {
    nanobind::class_<PeerInfo>(m, "PeerInfo")
        .def(nanobind::init<>())
        .def_rw("peer_id", &PeerInfo::peer_id)
        .def_rw("transport", &PeerInfo::transport);
});

3) Module entry point (shared-object boundary)

Use this only for the package that has its own .so and NB_MODULE entry point. Do not pair it with EASYBIND_NS_MODULE for the same my_pkg name. If you need to add bindings from another file, use EASYBIND_NS_MODULE_EXTEND to extend the same module node instead.

#include <pymergetic/easybind/bind.hpp>

EASYBIND_NS_MODULE_SHARED_OBJECT(my_pkg, my_pkg, m, true, {
    m.doc() = "my_pkg module";
});

4) Extend from another file

#include <pymergetic/easybind/bind.hpp>

EASYBIND_NS_MODULE_EXTEND(my_pkg, m, {
    m.def("ping", [] { return "pong"; });
});

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pymergetic_easybind-0.3.17.tar.gz (53.5 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

pymergetic_easybind-0.3.17-cp314-cp314-win_amd64.whl (651.2 kB view details)

Uploaded CPython 3.14Windows x86-64

pymergetic_easybind-0.3.17-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (295.9 kB view details)

Uploaded CPython 3.14manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

pymergetic_easybind-0.3.17-cp313-cp313-win_amd64.whl (638.5 kB view details)

Uploaded CPython 3.13Windows x86-64

pymergetic_easybind-0.3.17-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (295.9 kB view details)

Uploaded CPython 3.13manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

pymergetic_easybind-0.3.17-cp312-cp312-win_amd64.whl (639.4 kB view details)

Uploaded CPython 3.12Windows x86-64

pymergetic_easybind-0.3.17-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (295.8 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

pymergetic_easybind-0.3.17-cp311-cp311-win_amd64.whl (640.6 kB view details)

Uploaded CPython 3.11Windows x86-64

pymergetic_easybind-0.3.17-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (296.3 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

File details

Details for the file pymergetic_easybind-0.3.17.tar.gz.

File metadata

  • Download URL: pymergetic_easybind-0.3.17.tar.gz
  • Upload date:
  • Size: 53.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pymergetic_easybind-0.3.17.tar.gz
Algorithm Hash digest
SHA256 9b8f2cc5e2f8487b34592aebde69288cf79662074a060f3fe5caafee03c191fd
MD5 d7775c631db01e68ea654170d4bd74a4
BLAKE2b-256 79e6018011a40bf30998442682f4d7d2623f2206beca2cc459cc4e2930f7553b

See more details on using hashes here.

File details

Details for the file pymergetic_easybind-0.3.17-cp314-cp314-win_amd64.whl.

File metadata

File hashes

Hashes for pymergetic_easybind-0.3.17-cp314-cp314-win_amd64.whl
Algorithm Hash digest
SHA256 92038c1e35e81355f7d5c67d64eeec34ef102f66f48097f9c16975f00294a7fc
MD5 d6a337f59d0aaf21e6092fa1efb6aac2
BLAKE2b-256 7117850e671e17c600a854857aeb53447a2cd7dbaec74715607d2470f74c966d

See more details on using hashes here.

File details

Details for the file pymergetic_easybind-0.3.17-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pymergetic_easybind-0.3.17-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 005d8869a67d9baa05083038ea055bacf467fea11c9be9597e90ba5599dd3e96
MD5 3a194e713ebc3a3b93476ad1728a4114
BLAKE2b-256 ee775fea6f75878e14955dee5b1f8f0340fc3ae6110d6e3c7cb4b0aa93e09375

See more details on using hashes here.

File details

Details for the file pymergetic_easybind-0.3.17-cp313-cp313-win_amd64.whl.

File metadata

File hashes

Hashes for pymergetic_easybind-0.3.17-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 7bd82c7f8974e45d818026248a4406cb0076eb72bcedc0af101947beb7db7816
MD5 7bc88acbd338c39f737a86aaf269868f
BLAKE2b-256 f623d43d05ae8fa3df8a42373e9328532d7f2862b695d4c31c482b14f5cb16a9

See more details on using hashes here.

File details

Details for the file pymergetic_easybind-0.3.17-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pymergetic_easybind-0.3.17-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 5421e3b6d382f425ced9b2786471284d5fcc6f7e60b11f4a0c69d656b321c3d1
MD5 7e114c2c26cc034fd4868d47d5587227
BLAKE2b-256 286ee903db0f7b21157fe9ca38863f7f0ba7b8f29ea79a9127c13dad05fa8216

See more details on using hashes here.

File details

Details for the file pymergetic_easybind-0.3.17-cp312-cp312-win_amd64.whl.

File metadata

File hashes

Hashes for pymergetic_easybind-0.3.17-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 8f0d7bcffe87d01285029b4e676b052091e998496e9e9a9f75305c895206a21a
MD5 b92af3a8bab75929616e06aa3ceaf2f6
BLAKE2b-256 d8c7cbe10d40933f5ca3fb224aa822c0d7dde0209d315eaaf8f146b21ae64fef

See more details on using hashes here.

File details

Details for the file pymergetic_easybind-0.3.17-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pymergetic_easybind-0.3.17-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 e22a525ec64fadce0ea2d18d27af223a2289edf1080b0fe76950593ce56d2344
MD5 b18f6815da02331fb734fe5a5d076c3b
BLAKE2b-256 7453915d4fc0947aaf34f2f1e5ef97e7f07ca1712847c4ebea7812634438e813

See more details on using hashes here.

File details

Details for the file pymergetic_easybind-0.3.17-cp311-cp311-win_amd64.whl.

File metadata

File hashes

Hashes for pymergetic_easybind-0.3.17-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 73115565994fcbc101d0290726aadcd12f199b8a1cf50ee88e7cc0e2f1d224d2
MD5 736c773920a2ed1c9e5dfe8e8f75cbc3
BLAKE2b-256 96b6f11f044f0892a059db49e1ebccada4724718007115387f876838f926e7ee

See more details on using hashes here.

File details

Details for the file pymergetic_easybind-0.3.17-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pymergetic_easybind-0.3.17-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 67b390998b59ce407262d0fab9a35eae29d568c761a912c150a8b9456c9af592
MD5 a7c6815f68da495c0ab9bdd8bca9ab2f
BLAKE2b-256 76f13c1ebe72a853269be80bd23697ff574434948c9f30c7354a59d28037d051

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page