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.13.tar.gz (54.2 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.13-cp314-cp314-win_amd64.whl (651.2 kB view details)

Uploaded CPython 3.14Windows x86-64

pymergetic_easybind-0.3.13-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.13-cp313-cp313-win_amd64.whl (638.5 kB view details)

Uploaded CPython 3.13Windows x86-64

pymergetic_easybind-0.3.13-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.13-cp312-cp312-win_amd64.whl (639.4 kB view details)

Uploaded CPython 3.12Windows x86-64

pymergetic_easybind-0.3.13-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.13-cp311-cp311-win_amd64.whl (640.6 kB view details)

Uploaded CPython 3.11Windows x86-64

pymergetic_easybind-0.3.13-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.13.tar.gz.

File metadata

  • Download URL: pymergetic_easybind-0.3.13.tar.gz
  • Upload date:
  • Size: 54.2 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.13.tar.gz
Algorithm Hash digest
SHA256 70e9127e906734f40f45083ebef14c65426b62496ebc63e45318953860fa6472
MD5 43929d5ec678ddc025e97964a2a1b2c1
BLAKE2b-256 1d7641b621662489400d7a032137c80055b6c3427d52c1f5125180761b1546eb

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pymergetic_easybind-0.3.13-cp314-cp314-win_amd64.whl
Algorithm Hash digest
SHA256 57a24b1e9180bfdfb8bde8986587b902b234dcd959d52f1b412c7668f8e5afd1
MD5 adc83b0b86192f15493d35f735bad000
BLAKE2b-256 8967d80ec09dcd20f63b800cf3b2162c26a209cd7821d53607ccecb397e7cec3

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pymergetic_easybind-0.3.13-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 fb0431068728195d33619c9832e9e3c95873f7c4bd4c3354c7d41c1e0a271193
MD5 1c2ec2bef04391755a0f83467c5e36c4
BLAKE2b-256 8c1bd652311f4ac8c46b3d7ffc5b7fee23e13243122c3e6ef01903e183e3d508

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pymergetic_easybind-0.3.13-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 0d5ba5d5f90252e29f0055ea60a2352577f62080790fcb4f82f3910279d4a4cc
MD5 a9a20c258bd83427fcb4ee5a96bebb9a
BLAKE2b-256 76e222314427d9171bcb2febd32e7887366ddbbc633633fa50d32229ef907dd3

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pymergetic_easybind-0.3.13-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 95216f821cb24ab15113dbb5de8b479ed7a635c5c5f3b43c675e845f71fe4c3b
MD5 32cfab3d400a64e2d4ce55c1877100ea
BLAKE2b-256 97ab0823c5b949f257e0af1e5fa9f6dfbaf95137cea9bbb239bee99cccd29438

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pymergetic_easybind-0.3.13-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 2e112efa8500090f5201a1f3806f2c6d585fc21f1a3c942e7901f10f9ce00144
MD5 9386f62e3c4b26e765c82cbe97c9162e
BLAKE2b-256 64a774fff39a6d9a0274e3e9d7590113e90c7af44e074705007dbba9c4227c34

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pymergetic_easybind-0.3.13-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 94aa0f7243d91094d4f0c5897d6013e77b19567e8036c86cc5f0413bd30902f9
MD5 8f66de3acae526114fe2b58b366e7124
BLAKE2b-256 b1e4242b5950b80114247dd08d7e640b4d017afc39ca2fb2558762f468fa47e0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pymergetic_easybind-0.3.13-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 4145e5e5f32116e7b24255fc5c544da251ca5d108a9b90959706ac7117f828f5
MD5 ee46363d83a1d265e55daf4fe6a8b21c
BLAKE2b-256 b8ccafec3ba7a45284d0614a096588456a68fcf09d9e59c4492177ff2ffb0bd6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pymergetic_easybind-0.3.13-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 c5ced728d48cdc9e5dfb919b06d24a207fee7fe3abadf8cce40531547247ab24
MD5 109b8382c831522faede4b1c70911579
BLAKE2b-256 3f0e12157423adede368f3de71f31dc9c16bdebae171c929ee6f2335472e98b3

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