From bd7bfbf1fdc4b380d5c762958215a1be7affc376 Mon Sep 17 00:00:00 2001 From: stroblme Date: Thu, 29 Oct 2026 17:10:24 +0100 Subject: [PATCH] Move to nanobind 3.1 and release 8.0.1.3 The handle caster follows nanobind 3's renamed detail API (keep_alive_cb, NB_CALL(nb_type_put), uint32_t caster flags). Bound surface unchanged per sigdiff; list iteration ~4x faster. --- pyproject.toml | 4 ++-- scripts/_env.sh | 8 ++++---- src/common/occt_handle.h | 17 +++++++++-------- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 65a3c8d..f0f8023 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [build-system] -requires = ["scikit-build-core>=0.11", "nanobind>=2.7,<3"] +requires = ["scikit-build-core>=0.11", "nanobind>=3.1,<4"] build-backend = "scikit_build_core.build" [project] @@ -9,7 +9,7 @@ name = "n3xd-ocp" # .devN suffix: the registry never allows republishing a version, and its # cleanup rule collects only the dev ones. CMake asserts the prefix matches # the OCCT it found. -version = "8.0.1.2" +version = "8.0.1.3" description = "nanobind bindings for the OpenCASCADE geometry kernel (drop-in OCP)" readme = "README.md" requires-python = ">=3.12" diff --git a/scripts/_env.sh b/scripts/_env.sh index 5f3e292..d037489 100755 --- a/scripts/_env.sh +++ b/scripts/_env.sh @@ -24,10 +24,10 @@ if [ ! -x "$VENV/bin/python" ]; then "$VENV/bin/pip" install -q --upgrade pip # numpy is a test dependency only: the n3xd_ocp bulk APIs hand back # ndarrays, so their tests need it to check the results. - # nanobind 3 reworked the type-caster and rv_policy interfaces - # occt_handle.h builds on, so moving to it is a deliberate bump, not - # something a fresh cache picks up. - "$VENV/bin/pip" install -q build "nanobind<3" scikit-build-core pytest numpy + # occt_handle.h builds on nanobind's detail API, which moves between + # majors, so the next one is a deliberate bump, not something a fresh + # cache picks up. + "$VENV/bin/pip" install -q build "nanobind>=3.1,<4" scikit-build-core pytest numpy fi PY="$VENV/bin/python" export PY VENV CACHE diff --git a/src/common/occt_handle.h b/src/common/occt_handle.h index 5b42079..bb89010 100644 --- a/src/common/occt_handle.h +++ b/src/common/occt_handle.h @@ -44,10 +44,10 @@ NAMESPACE_BEGIN(detail) inline NB_NOINLINE void occt_handle_keep_alive(opencascade::handle &&h, PyObject *o) noexcept { - keep_alive(o, new opencascade::handle(std::move(h)), - [](void *p) noexcept { - delete (opencascade::handle *) p; - }); + keep_alive_cb(o, new opencascade::handle(std::move(h)), + [](void *p) noexcept { + delete (opencascade::handle *) p; + }); } template @@ -64,7 +64,7 @@ struct type_caster< "Conversion of opencascade::handle requires that T is " "bound through nanobind's regular class mechanism."); - bool from_python(handle src, uint8_t flags, + bool from_python(handle src, uint32_t flags, cleanup_list *cleanup) noexcept { // A null handle is OCCT's absent value and maps to None in both // directions; several APIs (BRep_Tool::Surface on a degenerate edge, @@ -74,7 +74,7 @@ struct type_caster< return true; } - flags &= ~((uint8_t) cast_flags::convert); + flags &= ~cast_flags::convert; Caster caster; if (!caster.from_python(src, flags, cleanup)) @@ -106,8 +106,9 @@ struct type_caster< // dynamic type: BRep_Tool::Surface returning a Geom_Surface handle to // a plane arrives in Python as Geom_Plane when that class is bound. bool is_new = false; - handle result = nb_type_put_p(&typeid(Td), &typeid(*ptr), (void *) ptr, - rv_policy::reference, cleanup, &is_new); + handle result = NB_CALL(nb_type_put)( + NB_CTX_C(cleanup), &typeid(Td), &typeid(*ptr), (void *) ptr, + rv_policy::reference, cleanup, &is_new); // Only a freshly created wrapper takes a reference. Attaching one per // conversion would pile up redundant handles on a long-lived object