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

Uploaded CPython 3.14Windows x86-64

pymergetic_easybind-0.3.12-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (296.2 kB view details)

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

pymergetic_easybind-0.3.12-cp313-cp313-win_amd64.whl (638.6 kB view details)

Uploaded CPython 3.13Windows x86-64

pymergetic_easybind-0.3.12-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (296.1 kB view details)

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

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

Uploaded CPython 3.12Windows x86-64

pymergetic_easybind-0.3.12-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (296.1 kB view details)

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

pymergetic_easybind-0.3.12-cp311-cp311-win_amd64.whl (640.7 kB view details)

Uploaded CPython 3.11Windows x86-64

pymergetic_easybind-0.3.12-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (296.5 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.12.tar.gz.

File metadata

  • Download URL: pymergetic_easybind-0.3.12.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.12.tar.gz
Algorithm Hash digest
SHA256 1b00c058ecb9da0dd02fcd475bca081f775e73f29521f628025e5f278eb707f4
MD5 9a07cd44907cab4cb3c181ee581dddd9
BLAKE2b-256 ef977515e8516d94ce055f7ee80af1cdad15dbfb2921e765fd635ef048c10e3b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pymergetic_easybind-0.3.12-cp314-cp314-win_amd64.whl
Algorithm Hash digest
SHA256 07f7cbb6ef581e02a26a385a72f13d0945933a80203b69c55d54138d4181a8ff
MD5 66ec40b201b35bd7400004983f025219
BLAKE2b-256 6e48c43a408b49ed93c140c93d899d22229c3e980543943b107a6f3195193e1d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pymergetic_easybind-0.3.12-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 9d13211705b460b42c809b9e1f01f73da1a2b13fe295f34908a0e70e61d8a057
MD5 ac43df88bd54a72bae207cb6ca27f100
BLAKE2b-256 76ae68b8dd44e33081af140236b2069948fe6df33cc88eade5bc6ec2f2ae8a27

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pymergetic_easybind-0.3.12-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 43bd90da506b1032bec228c09de675f4b7af0acf9e7c3a560fca48d2b76ca05e
MD5 4e7774e65c8103d3bc1fd7fe82e59f81
BLAKE2b-256 3cf64a0327c8b4893d188c320b6f2fcaeeb12e1ab03c57ede5f71e49df645374

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pymergetic_easybind-0.3.12-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 69b4408c0a34d005e5eb0d4f69aebf923a5063dc5ed0666dd350fc9cb329cba0
MD5 e9bb30465b882ab28108e1785ffa4b71
BLAKE2b-256 6bf080db0c54a4f8ab97742274c88eb87ea052335c8ac7e41ec3b48845339426

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pymergetic_easybind-0.3.12-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 7a0ec9c3cf2ba9a287c9f84c7c1ad13d2d9b8fd1377e6b34f9f4f9919fa211c4
MD5 1615762f63d299b85b1858054a81d2bb
BLAKE2b-256 6834e2983b2df86d40dba7928a8851c6347435185327e988f06ca211530b8284

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pymergetic_easybind-0.3.12-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 7df7cd5eb4e4fb9ad418b0f13738f6867a2ffde0067b605464c4333ec604bd93
MD5 997b3c10559046834175eb1091f59bc4
BLAKE2b-256 56d7a9bb43783400afe6f1d1bfc3c810641d0d3cf4bd102c6905f33057de74ac

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pymergetic_easybind-0.3.12-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 819e4c113e68a2a914a5ac4ca83ab047f4e70fc1cd6a459185343da07faa6bb7
MD5 7151538a117d253ae04bf77e3fb372b3
BLAKE2b-256 aefb302cdf45ca3c255a5ea655bb9cb7a5182e6db70cb46adaf72c1a5016c97b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pymergetic_easybind-0.3.12-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 1b03d66bb0a13ec37fcf3841961d00ddf0ebaa4eb47617816990c40738bfe6cb
MD5 05378df0f0ba15e3340c7073266335f8
BLAKE2b-256 de0a29d99c2a4cdfbcd08713342dfdce184085ccea3bfb6b4b840b493505227c

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