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.
This commit is contained in:
2026-10-29 17:10:24 +01:00
parent 407ef262ba
commit bd7bfbf1fd
3 changed files with 15 additions and 14 deletions
+2 -2
View File
@@ -1,5 +1,5 @@
[build-system] [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" build-backend = "scikit_build_core.build"
[project] [project]
@@ -9,7 +9,7 @@ name = "n3xd-ocp"
# .devN suffix: the registry never allows republishing a version, and its # .devN suffix: the registry never allows republishing a version, and its
# cleanup rule collects only the dev ones. CMake asserts the prefix matches # cleanup rule collects only the dev ones. CMake asserts the prefix matches
# the OCCT it found. # 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)" description = "nanobind bindings for the OpenCASCADE geometry kernel (drop-in OCP)"
readme = "README.md" readme = "README.md"
requires-python = ">=3.12" requires-python = ">=3.12"
+4 -4
View File
@@ -24,10 +24,10 @@ if [ ! -x "$VENV/bin/python" ]; then
"$VENV/bin/pip" install -q --upgrade pip "$VENV/bin/pip" install -q --upgrade pip
# numpy is a test dependency only: the n3xd_ocp bulk APIs hand back # numpy is a test dependency only: the n3xd_ocp bulk APIs hand back
# ndarrays, so their tests need it to check the results. # 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 nanobind's detail API, which moves between
# occt_handle.h builds on, so moving to it is a deliberate bump, not # majors, so the next one is a deliberate bump, not something a fresh
# something a fresh cache picks up. # cache picks up.
"$VENV/bin/pip" install -q build "nanobind<3" scikit-build-core pytest numpy "$VENV/bin/pip" install -q build "nanobind>=3.1,<4" scikit-build-core pytest numpy
fi fi
PY="$VENV/bin/python" PY="$VENV/bin/python"
export PY VENV CACHE export PY VENV CACHE
+9 -8
View File
@@ -44,10 +44,10 @@ NAMESPACE_BEGIN(detail)
inline NB_NOINLINE void inline NB_NOINLINE void
occt_handle_keep_alive(opencascade::handle<Standard_Transient> &&h, occt_handle_keep_alive(opencascade::handle<Standard_Transient> &&h,
PyObject *o) noexcept { PyObject *o) noexcept {
keep_alive(o, new opencascade::handle<Standard_Transient>(std::move(h)), keep_alive_cb(o, new opencascade::handle<Standard_Transient>(std::move(h)),
[](void *p) noexcept { [](void *p) noexcept {
delete (opencascade::handle<Standard_Transient> *) p; delete (opencascade::handle<Standard_Transient> *) p;
}); });
} }
template <typename T> template <typename T>
@@ -64,7 +64,7 @@ struct type_caster<
"Conversion of opencascade::handle<T> requires that T is " "Conversion of opencascade::handle<T> requires that T is "
"bound through nanobind's regular class mechanism."); "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 { cleanup_list *cleanup) noexcept {
// A null handle is OCCT's absent value and maps to None in both // A null handle is OCCT's absent value and maps to None in both
// directions; several APIs (BRep_Tool::Surface on a degenerate edge, // directions; several APIs (BRep_Tool::Surface on a degenerate edge,
@@ -74,7 +74,7 @@ struct type_caster<
return true; return true;
} }
flags &= ~((uint8_t) cast_flags::convert); flags &= ~cast_flags::convert;
Caster caster; Caster caster;
if (!caster.from_python(src, flags, cleanup)) 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 // dynamic type: BRep_Tool::Surface returning a Geom_Surface handle to
// a plane arrives in Python as Geom_Plane when that class is bound. // a plane arrives in Python as Geom_Plane when that class is bound.
bool is_new = false; bool is_new = false;
handle result = nb_type_put_p(&typeid(Td), &typeid(*ptr), (void *) ptr, handle result = NB_CALL(nb_type_put)(
rv_policy::reference, cleanup, &is_new); 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 // Only a freshly created wrapper takes a reference. Attaching one per
// conversion would pile up redundant handles on a long-lived object // conversion would pile up redundant handles on a long-lived object