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.19.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.19-cp314-cp314-win_amd64.whl (651.2 kB view details)

Uploaded CPython 3.14Windows x86-64

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

Uploaded CPython 3.13Windows x86-64

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

Uploaded CPython 3.12Windows x86-64

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

Uploaded CPython 3.11Windows x86-64

pymergetic_easybind-0.3.19-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.19.tar.gz.

File metadata

  • Download URL: pymergetic_easybind-0.3.19.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.19.tar.gz
Algorithm Hash digest
SHA256 cbd395b5e8c1751bc09e0574b31cd434d24b179a37878b95ef718b831b569a01
MD5 ddd7948b0f8dafc6dab863dce5847861
BLAKE2b-256 f9f81b191ab3ee5707aeecfe031e714ddb628615ea261f36215002164ed133d0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pymergetic_easybind-0.3.19-cp314-cp314-win_amd64.whl
Algorithm Hash digest
SHA256 b4c82c9ba4320bb97866eafcdc6d5acd58cb58c159830583510103b093b4a75e
MD5 3c50076b94bf741094eed66afe11f8ba
BLAKE2b-256 5e2670c8bb0292faea05f3a6068dc4999a02897bdab909fe829f65a4cf3f11ce

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pymergetic_easybind-0.3.19-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 515126c37620bb6e8df22ffdabd5affa4068e9605e653c23ea0db8a69b723d9f
MD5 97b6cf09f828ffea106692426849b833
BLAKE2b-256 f0dc01c7ff9b048ea94adc86496a02949547d0ea36d7cb6d4cb6f4dda9b0fb5d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pymergetic_easybind-0.3.19-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 fd4386596d127504516f62506159e60f896352c20e1cc601cbe6bf5ae66699eb
MD5 d6e244f2e87e5bedfa30557aa3bb1fe3
BLAKE2b-256 06e23dae478d9f28c13b5e081b2633929eb023335d7f52fd0ed0169b72b3d806

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pymergetic_easybind-0.3.19-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 826591a5db4b5f68fdb3a4011d070725e642f414f945de5230bb3d48b2acfce1
MD5 7943bd42f3d162c7c9fe7b7123983ce9
BLAKE2b-256 4010ae40d73d91b49b014b210ca711dff802ddc152dd9744280a462a2300543a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pymergetic_easybind-0.3.19-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 6a7559c9e66e4d5e41205b13f420a1dd5d9f44044494d35a9da76dd376333800
MD5 2943621ff385e0071e39f00f3d0d40e9
BLAKE2b-256 7cb5d5c90caa64231df9683d10213ea69f496c16f3613bccaa561253d9a4288f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pymergetic_easybind-0.3.19-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 29122abb80065056c96f360e1d88081ef597b3f8f7d69c384dc78bd0aa99aa96
MD5 134a4c9d813692fd3d1e4673e4b891d8
BLAKE2b-256 694da43937333789ed284f5ed08b6380c55c580ed632c100e22deffeab997dd2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pymergetic_easybind-0.3.19-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 3ab6241b6a851df5fd70b5aa0edcb7c3cd03dab9554a418884194dfd0b8f4093
MD5 bd26cbcecfafe58612aa27e25d58aebb
BLAKE2b-256 1431fd010a642705869b8756b47e06f34a69cce983c7997477dc8e584c2b844b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pymergetic_easybind-0.3.19-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 eb7d7e4224432243d9269652f60b592039fff46989e5e9c43b1a1f184eb30abb
MD5 520295fa3b18c1891b0a2a58e0a8a969
BLAKE2b-256 500c48549532924a0dde79eb3f0531e93a7ac0932ec003668fa65f9f447d6ed4

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