Changelog¶
nanobind uses a semantic versioning policy for its API. It also has a separate ABI version that is not subject to semantic versioning.
The ABI version is relevant whenever a type binding from one extension module should be visible in another nanobind-based extension module. In this case, both modules must use the same nanobind ABI version, or they will be isolated from each other. Releases that don’t explicitly mention an ABI version below inherit that of the preceding release.
Version 2.4.0 (Dec 6, 2024)¶
Added a function annotation
nb::call_policy<Policy>()
which supports custom function wrapping logic, callingPolicy::precall()
before the bound function andPolicy::postcall()
after. This is a low-level interface intended for advanced users. The precall and postcall hooks are able to observe the Python objects forming the function arguments and return value, and the precall hook can change the arguments. See the linked documentation for more details, important caveats, and an example policy. (PR #767)nb::make_iterator
now accepts its iterator arguments by value, rather than by forwarding reference, in order to eliminate the hazard of storing a dangling C++ iterator reference in the returned Python iterator object. (PR #788)The
std::variant
type_caster now does two passes when converting from Python. The first pass is done without implicit conversions. This fixes an issue wherestd::variant<U, T>
might cast a Python object wrapping aT
to aU
if there is an implicit conversion available fromT
toU
. (issue #769)Restored support for constructing types with an overloaded
__new__
that takes no arguments, which regressed with the constructor vector call acceleration that was added in nanobind 2.2.0. (issue #786)Bindings for augmented assignment operators (as generated, for example, by
.def(nb::self += nb::self)
) now return the same object in Python in the typical case where the C++ operator returns a reference to*this
. Previously, aftera += b
,a
would be replaced with a copy. (PR #803)Added an overload to
nb::isinstance
which tests if a Python object is an instance of a Python class. This is in addition to the existing overload, which tests if a Python object is an instance of a bound C++ class. (PR #805).Added support for overriding static properties, such as those defined using
def_prop_ro_static
, in subclasses. Previously this would fail with an error. (PR #806).Other minor fixes and improvements. (PRs #771, #772, #748, and #753)
Version 2.3.0¶
There is no version 2.3.0 due to a deployment mishap.
Version 2.2.0 (October 3, 2024)¶
nanobind can now target free-threaded Python, which replaces the Global Interpreter Lock (GIL) with a fine-grained locking scheme (see PEP 703) to better leverage multi-core parallelism. A separate documentation page explains this in detail (PRs #695, #720)
nanobind has always used PEP 590 vector calls to efficiently dispatch calls to function and method bindings, but it lacked the ability to do so for constructors (e.g.,
MyType(arg1, arg2, ...)
).Version 2.2.0 adds this missing part, which accelerates object construction by up to a factor of 2×. The difference is especially pronounced when passing keyword arguments to constructors. Note that this improvement only applies to Python version 3.9 and newer (PR #706, commits #e24d7f, #0acecb, #77f910, #2c96d5).
A new
nb::is_flag()
annotation innb::enum_<T>()
produces enumeration bindings deriving fromenum.Flag
, which enables bit-wise combination using compatible operators (&
,|
,^
, and~
). Further combining the annotation withnb::is_arithmetic()
creates enumerations deriving fromenum.IntFlag
. (PRs #599, #688, #688, #727, #732)A refactor of
nb::ndarray<...>
was an opportunity to realize three usability improvements:The constructor used to return new nd-arrays from C++ now considers all template arguments:
Shape:
nb::shape<3, 4, 5>
, etc.Device type:
nb::device::cpu
,nb::device::cuda
, etc.Framework:
nb::numpy
,nb::pytorch
, etc.Data type:
uint64_t
,std::complex<double>
, etc.
Previously, only the framework and data type annotations were taken into account when returning nd-arrays, while all of them were examined when accepting arrays during overload resolution. This inconsistency was a repeated source of confusion among users.
To give an example, the following now works out of the box without the need to redundantly specify the shape and strides to the
Array
constructor below:using Array = nb::ndarray<float, nb::numpy, nb::shape<4, 4>, nb::f_contig>; struct Matrix4f { float m[4][4]; Array data() { return Array(m); } }; nb::class_<Matrix4f>(m, "Matrix4f") .def("data", &Matrix4f::data, nb::rv_policy::reference_internal);
A new nd-array
.cast()
method forces the immediate creation of a Python object with the specified target framework and return value policy, while preserving the type signature in return values. This is useful to return temporaries (e.g. stack-allocated memory) from functions.Added a new and more general mechanism
nanobind::detail::dtype_traits<T>
to declare custom ndarray data types likefloat16
orbfloat16
. The old interface (nanobind::ndarray_traits<T>
) still exists but is deprecated and will be removed in the next major release. See the documentation for details.
There are two minor but potentially breaking changes:
The nd-array type caster now interprets the
nb::rv_policy::automatic_reference
return value policy analogously to thenb::rv_policy::automatic
, which means that it references a memory region when the user specifies anowner
, and it otherwise copies. This makes it safe to use thenb::cast()
andnb::ndarray::cast()
functions that use this policy as a default.The
nb::any_contig
memory order annotation, which previously did nothing, now accepts C- or F-contiguous arrays and rejects non-contiguous ones.
For further details on the nd-array changes, see PR #721, For further details on the nd-array changes, see PR #742, and commit 4647ef.
The NVIDIA CUDA compiler (
nvcc
) is now explicitly supported and included in nanobind’s CI test suite (PR #710).
Added support for return value policy customization to the type casters of
Eigen::Ref<...>
andEigen::Map<...>
(commit 67316e).The
nb::ellipsis
type now renders as...
when used innb::typed<...>
(PR #705).The
nb::sig("...")
annotation now supports inline type parameter lists such asdef first[T](l: Sequence[T]) -> T
(PR #704).Fixed implicit conversion of complex nd-arrays. (issue #709)
Casting via
nb::cast
can now specify an owner object for use with thenb::rv_policy::reference_internal
return value policy (PR #667).The
std::optional<T>
type caster is now implemented in such a way that it can also accommodate non-STL frameworks, such as Boost, Abseil, etc. (PR #675)ABI version 15.
Minor fixes and improvements (PRs #703, #724, #723, #722, #715, #696, #693, commit 75d259).
Version 2.1.0 (Aug 11, 2024)¶
Temporary workaround for a internal compiler error in version 17.10 of the MSVC compiler. This workaround will be removed once fixed versions are deployed on GitHub actions. (issue #613, commit f2438b).
nanobind no longer prevents casting to a C++ container of pointers
T*
whereT
is a type with a user-defined type caster if the caster seems to operate by extracting aT*
from the Python object rather than aT
. This change was prompted by discussion #605.Switched nanobind wheel generation from setuptools to scikit-build-core (PR #618).
Improved handling of
const
-ness innb::ndarray
(PR #491).Keyword argument annotations are now properly supported with
nb::new_
, passed in the same way they would be withnb::init
. (issue #668)Ability to use
nb::cast
to create object with thenb::rv_policy::reference_internal
return value policy (PR #667).Enable
char
type caster to produce'\0'
(PR #661).Added
.def_static()
member tonb::enum_
, which had been lost in a redesign of the enumeration implementation in nanobind version 2.0.0. (commit 38990e).Fixes for two minor sources of memory leaks (PR #595, #647).
The nd-array wrapper
nb::ndarray
now properly handles CuPy arrays (#594).Added
nb::hash()
, a wrapper for the Pythonhash()
function (commit 91fafa5).Various minor
stubgen
fixes (PRs #667, #658, #632, #620, #592).
Version 2.0.0 (May 23, 2024)¶
The 2.0.0 release of nanobind is entirely dedicated to types [1]! The project has always advertised seamless Python ↔ C++ interoperability, and this release tries to bring a similar level of interoperability to static type checkers like MyPy, PyRight, PyType, and editors with interactive autocompletion like Visual Studio Code, PyCharm, and many other LSP-compatible IDEs.
This required work on three fronts:
Stub generation: the above tools all analyze Python code statically without running it. Because the import mechanism of compiled extensions depends the Python interpreter, these tools weren’t able to inspect the contents of nanobind-based extensions.
The usual solution involves writing stubs that expose the module contents to static analysis tools. However, writing stubs by hand is tedious and error-prone.
This release adds tooling to automatically extract stubs from existing extensions. The process is fully integrated into the CMake-based build system and explained in a new documentation section.
Better default annotations: once stubs were available, this revealed the next problem: the default nanobind-provided function and class signatures were too rudimentary, and this led to a user poor experience.
The release therefore improves many builtin type caster so that they produce more accurate type signatures. For example, the STL
std::vector<T>
caster now renders ascollections.abc.Sequence[T]
in stubs when it is used as an input, andlist[T]
when it is used as part of a return value. Thenb::make_*_iterator()
family of functions return typed iterators, etc.Advanced customization: a subset of the type signatures in larger binding projects will generally require further customization. The features listed below aim to enable precisely this:
In Python, many built-in types are generic and can be parameterized (e.g.,
list[int]
). Thenb::typed<T, Ts...>
wrapper enables such parameterization within C++ (for example, theint
-specialized list would be written asnb::typed<nb::list, int>
). Read more.The opposite is also possible: passing
nb::is_generic()
to the class binding constructornb::class_<MyType>(m, "MyType", nb::is_generic())
produces a generic type that can be parameterized in Python (e.g.
MyType[int]
). Read more.The
nb::sig
annotation overrides the signature of a function or method, e.g.:m.def("f", &f, nb::sig("def f(x: Foo = Foo(0)) -> None"), "docstring");
Each binding of an overloaded function can be customized separately. This feature can be used to add decorators or control how default arguments are rendered. Read more.
The
nb::sig
annotation can also override class signatures in generated stubs. Stubs often take certain liberties in deviating somewhat from the precise type signature of the underlying implementation. For example, the following annotation adds an abstract base class advertising that the class implements a typed iterator.using IntVec = std::vector<int>; nb::class_<IntVec>(m, "IntVec", nb::sig("class IntVec(collections.abc.Iterable[int])"));
Nanobind can’t subclass Python types, hence this declaration is technically untrue. On the flipside, such a declaration can assist static checkers and improve auto-completion in visual IDEs. This is fine since these tools only perform a static analysis and never import the actual extension. Read more.
The
nb::for_setter
andnb::for_getter
annotations enable passing function binding annotations (e.g., signature overrides) specifically to the setter or the getter part of a property.The
nb::arg("name")
argument annotation (and"name"_a
shorthand) now have a.sig("signature")
member to control how a default value is rendered in the stubs and docstrings. This provides more targeted control compared to overriding the entire function signature.Finally, nanobind’s stub generator supports pattern files containing custom stub replacement rules. This catch-all solution addresses the needs of advanced binding projects, for which the above list of features may still not be sufficient.
Most importantly, it was possible to support these improvements with minimal changes to the core parts of nanobind.
These release breaks API and ABI compatibility, requiring a new major version according to SemVer. The following changes are noteworthy:
The
nb::enum_<T>()
binding declaration is now a wrapper that creates either aenum.Enum
orenum.IntEnum
-derived type. Previously, nanobind relied on a custom enumeration base class that was a frequent source of friction for users.This change may break code that casts entries to integers, which now only works for arithmetic (
enum.IntEnum
-derived) enumerations. Replaceint(my_enum_entry)
withmy_enum_entry.value
to work around the issue.The
nb::bind_vector<T>()
andnb::bind_map<T>()
interfaces were found to be severely flawed since element access (__getitem__
) created views into the internal state of the STL type that were not stable across subsequent modifications.This could lead to unexpected changes to array elements and undefined behavior when the underlying storage was reallocated (i.e., use-after-free).
nanobind 2.0.0 improves these types so that they are safe to use, but this means that element access must now copy by default, potentially making them less convenient. The documentation of
nb::bind_vector<T>()
discusses the issue at length and presents alternative solutions.The functions
nb::make_iterator()
,nb::make_value_iterator()
andnb::make_key_iterator()
suffer from the same issue asnb::bind_vector()
explained above.nanobind 2.0.0 improves these operations so that they are safe to use, but this means that iterator access must now copy by default, potentially making them less convenient. The documentation of
nb::make_iterator()
discusses the issue and presents alternative solutions.The
nb::raw_doc
annotation was found to be too inflexible and was removed in this version.The
nb::typed
wrapper listed above actually already existed in previous nanobind versions but was awkward to use, as it required the user to provide a custom type formatter. This release makes the interface more convenient.The
nb::any
placeholder to specify an unconstrainednb::ndarray
axis was removed. This name was given to a new wrapper typenb::any
indicatingtyping.Any
-typed values.All use of
nb::any
in existing code must be replaced with-1
(for example,nb::shape<3, nb::any, 4>
→nb::shape<3, -1, 4>
).Keyword-only arguments are now supported, and can be indicated using the new
nb::kw_only()
function annotation. (PR #448).nanobind classes now permit overriding
__new__
, in order to support C++ singletons, caches, and other types that expose factory functions rather than ordinary constructors. Read the section on customizing Python object creation for more details. (PR #473).When binding methods on a class
T
, nanobind will now produce a Python function that expects a self argument of typeT
. Previously, it would use the type of the member pointer to determine the Python function signature, which could be a base ofT
, which would create problems if nanobind did not know about that base. (PR #471).nanobind can now handle keyword arguments that are not interned, which avoids spurious
TypeError
exceptions in constructs likefn(**pickle.loads(...))
. The speed of normal function calls (which generally do have interned keyword arguments) should be unaffected. (PR #469).The
owner=nb::handle()
default value of thenb::ndarray
constructor was removed since it was bug-prone. You now have to specify the owner explicitly. The previous default (nb::handle()
) continues to be a valid argument.There have been some changes to the API for type casters in order to avoid undefined behavior in certain cases. (PR #549).
Type casters that implement custom cast operators must now define a member function template
can_cast<T>()
, which returns false ifoperator cast_t<T>()
would raise an exception and true otherwise.can_cast<T>()
will be called only after a successful call tofrom_python()
, and might not be called at all if the caller ofoperator cast_t<T>()
can cope with a raised exception. (Users of theNB_TYPE_CASTER()
convenience macro need not worry about this; it produces cast operators that never raise exceptions, and therefore provides acan_cast<T>()
that always returns true.)Many type casters for container types (
std::vector<T>
,std::optional<T>
, etc) implement theirfrom_python()
methods by delegating to another, “inner” type caster (T
in these examples) that is allocated on the stack insidefrom_python()
. Container casters implemented in this way should make two changes in order to take advantage of the new safety features:Wrap your
flags
(received as an argument of the outer caster’sfrom_python
method) inflags_for_local_caster<T>()
before passing them toinner_caster.from_python()
. This allows nanobind to prevent some casts that would produce dangling pointers or references.If
inner_caster.from_python()
succeeds, then also verifyinner_caster.template can_cast<T>()
before you executeinner_caster.operator cast_t<T>()
. A failure ofcan_cast()
should be treated the same as a failure offrom_python()
. This avoids the possibility of an exception being raised through the noexceptload_python()
method, which would crash the interpreter.
The previous
cast_flags::none_disallowed
flag has been removed; it existed to avoid one particular source of exceptions from a cast operator, butcan_cast<T>()
now handles that problem more generally.ABI version 14.
Footnote
Version 1.9.2 (Feb 23, 2024)¶
Nanobind instances can now be made weak-referenceable by specifying the
nb::is_weak_referenceable
tag in thenb::class_<..>
constructor. (PR #335, commits fc7709, 3562f6).Ensure that the GIL is held when releasing
nb::ndarray
. (issue #377, commit a968e8).nb::try_cast()
no longer crashes the interpreter when attempting to cast a PythonNone
to a C++ type that was bound usingnb::class_<...>
. Previously this would raise an exception from the cast operator, which would result in a call tostd::terminate()
becausetry_cast()
is declarednoexcept
. (PR #386).Fixed memory corruption in a PyPy-specific code path in
nb::module_::def_submodule()
(commit 21eaff).Don’t implicitly convert complex to non-complex nd-arrays. (issue #364, commit ea2569).
Support for non-assignable types in the
std::optional<T>
type caster (PR #358, commit 9c9b64).nanobind no longer assumes that docstrings provided to function binding (of type
const char *
) have an infinite lifetime and it makes copy. (issue #393, commit b3b6f4).Don’t pass compiler flags if they may be unsupported by the used compiler. This gets NVCC to work out of the box (that said, this change does not elevate NVCC to being an officially supported compiler). (issue #383, commit a307ea).
Added a CMake install target to the nanobind build system. (PR #356, commit 6bde65, commit 978dbb, commit f5d8de).
ABI version 13.
Minor fixes and improvements.
Version 1.9.0-1.9.1 (Feb 18, 2024)¶
Releases withdrawn because of a regression. The associated changes are listed above in the 1.9.2 release notes.
Version 1.8.0 (Nov 2, 2023)¶
nanobind now considers two C++
std::type_info
instances to be equal when their mangled names match. The previously used pointer comparison was fast but fragile and often caused multi-part extensions to not recognize each other’s types. This version introduces a two-level caching scheme (search by pointer, then by name) to fix such problems once and for all, while avoiding the cost of constantly comparing very long mangled names. (commit b515b1).Fixed casting of complex-valued constant
nb::ndarray<T>
instances. (PR #338, commit ba8c7f).Added a type caster for
std::nullopt_t
(PR #350).Added the missing C++ → Python portion of the type caster for
Eigen::Ref<..>
(PR #334).Minor fixes and improvements.
ABI version 12.
Version 1.7.0 (Oct 19, 2023)¶
New features¶
The nd-array class
nb::ndarray<T>
now supports complex-valuedT
(e.g.,std::complex<double>
). For this, the header filenanobind/stl/complex.h
must be included. (PR #319, commit 6cbd13).Added the function
nb::del()
, which takes an arbitrary accessor object as input and tries to delete the associated entry. The C++ statementnb::del(o[key]);
is equivalent to
del o[key]
in Python. (commit 4dd745).Exposed several convenience functions for raising exceptions as public API:
nb::raise
,nb::raise_type_error
, andnb::raise_python_error
. (commit 0b7f3b).Added
nb::globals()
. (PR #311, commit f0a9eb).The
char*
type caster now acceptsnullptr
and converts it into a PythonNone
object. (PR #318, commit 30a6ba).Added the function
nb::is_alive()
, which returnsfalse
when nanobind was destructed by Python (e.g., during interpreter shutdown) making further use of the API illegal. (commit b431d0).Minor fixes and improvements.
ABI version 11.
Bugfixes¶
The behavior of the
nb::keep_alive<Nurse, Patient>
function binding annotation was changed as follows: when the function call requires the implicit conversion of an argument, the lifetime constraint now applies to the newly produced argument instead of the original object. The change was rolled into a minor release since the former behavior is arguably undesirable and dangerous. (commit 9d4b2e).STL type casters previously raised an exception when casting a Python container containing a
None
element into a C++ container that was not able to representnullptr
(e.g.,std::vector<T>
instead ofstd::vector<T*>
). However, this exception was raised in a context where exceptions were not allowed, causing the process to beabort()
-ed, which is very bad. This issue is now fixed, and such conversions are refused. (PR #318, commits d1ad3b and 5f25ae).The STL sequence casters (
std::vector<T>
, etc.) now refuse to unpackstr
andbytes
objects analogous to pybind11. (commit 7e4a88).
Version 1.6.2 (Oct 3, 2023)¶
Added a missing include file used by the new intrusive reference counting sample implementation from v1.6.0. (commit 31d115).
Version 1.6.1 (Oct 2, 2023)¶
Version 1.6.0 (Oct 2, 2023)¶
New features¶
Several
nb::ndarray<..>
improvements:CPU loops involving nanobind nd-arrays weren’t getting properly vectorized. This release of nanobind adds views, which provide an efficient abstraction that enables better code generation. See the documentation section on array views for details. (commit 8f602e).
Added support for nonstandard arithmetic types (e.g.,
__int128
or__fp16
) in nd-arrays. See the documentation section for details. (commit 49eab2).Shape constraints like
nb::shape<nb::any, nb::any, nb::any>
are tedious to write. Now, there is a shorter form:nb::ndim<3>
. (commit 1350a5).Added an explicit constructor that can be used to add or remove nd-array constraints. (commit a1ac207).
Added the wrapper class
nb::weakref
. (commit 78887f).Added the methods
nb::dict::contains()
andnb::mapping::contains()
to the Python type wrappers. (commit 64d87a).Added
nb::exec()
andnb:eval()
. (PR #299).Added a type caster for
std::complex<T>
. (PR #292, commit dcbed4).Added an officially supported sample implementation of intrusive reference counting via the
intrusive_counter
intrusive_base
, andref
classes. (commit 3fa1af).
Bugfixes¶
Fixed a serious issue involving combinations of bound types (e.g.,
T
) and type casters (e.g.,std::vector<T>
), where nanobind was too aggressive in its use of move semantics. Calling a bound function from Python taking such a list (e.g.,f([t1, t2, ..])
) would destructt1, t2, ..
if the typeT
exposed a move constructor, which is highly non-intuitive and no longer happens as of this fix.Further investigation also revealed inefficiencies in the previous implementation where moves were actually possible but not done (e.g., for functions taking an STL vector by value). Some binding projects may see speedups as a consequence of this change. (issue #307, commit 122015).
Version 1.5.2 (Aug 24, 2023)¶
Fixed a severe issue with inheritance of the
Py_TPFLAGS_HAVE_GC
flag affecting classes that derive from other classes with anb::dynamic_attr
annotation. (issue #279, commit dbedad).Implicit conversion of nd-arrays to conform to contiguity constraints such as
c_contig
andf_contig
previously failed in some cases that are now addressed. (issue #278 commit ed929b).
Version 1.5.1 (Aug 23, 2023)¶
Fixed serious reference counting issue introduced in nanobind version 1.5.0, which affected the functions
python_error::traceback()
andpython_error::what()
, causing undefined behavior via use-after-free. Also addressed an unrelated minor UB sanitizer warning. (issue #277, commits 30d30c and c48b18).Extended the internal data structure tag so that it isolates different MSVC versions from each other (they are often not ABI compatible, see pybind11 issue #4779). This means that nanobind 1.5.1 effectively bumps the ABI version to “10.5” when compiling for MSVC, and the internals will be isolated from extensions built with nanobind v1.5.0 or older. (commit c7f3cd).
Incorporated fixes so that nanobind works with PyPy 3.10. (commits fb5508 and 2ed10a).
Fixed type caster for
std::vector<bool>
. (PR #256).Fixed compilation in debug mode on MSVC. (PR #253).
Version 1.5.0 (Aug 7, 2023)¶
Support for creating chained exceptions via the
nb::raise_from()
andnb::chain_error()
functions. (commits 041520 and beb699).Many improvements to the handling of return value policies in
nb::ndarray<..>
to avoid unnecessary copies. (commit ffd22b, a79575, and 6f0c3f).The
nb::ndarray<..>
class now has an additional convenience constructor that takes the shape and (optionally) strides usingstd::initializer_list
. (commit de1117).Added a non-throwing function
nb::try_cast()
as an alternative tonb::cast()
. (commit 6ca852).The
nb::list
andnb::tuple
default constructors now construct an empty list/tuple instead of an invalid null-initialized handle. (commit 506185)New low-level interface for wrapping existing C++ instances via
nb::inst_take_ownership()
nb::inst_reference()
. Also added convenience functions to replace the contents of an instance with that of another.nb::inst_replace_copy()
along withnb::inst_replace_move()
(commit 1c462d).Added a low-level abstraction around
nb::type_get_slot()
aroundPyType_GetSlot
, but with more consistent behavior across Python versions. (commit d555e9).The
nb::list::append()
method now performs perfect forwarding. (commit 2219d0).Inference of
automatic*
return value policy was entirely moved to the base C++ class type caster. (commit 1ff9df).Switch to the new Python 3.12 error status API if available. (commit 36751c).
Various minor fixes and improvements.
ABI version 10.
Version 1.4.0 (June 8, 2023)¶
Improved the efficiency of the function dispatch loop. (PR #227).
Significant improvements to the Eigen type casters (generalized stride handling to avoid unnecessary copies, support for conversion via
nb::cast()
, many refinements to theEigen::Ref<T>
interface). (PR #215).Added a
NB_DOMAIN
parameter tonanobind_add_module()
which can isolate extensions from each other to avoid binding clashes. See the associated FAQ entry for details. (commit 977119).Reduced the severity of nanobind encountering a duplicate type binding (commits f3b0e6, and 2c9124).
Support for pickling/unpickling nanobind objects. (commit 59843e).
ABI version 9.
Version 1.3.2 (June 2, 2023)¶
Version 1.3.1 (May 31, 2023)¶
CMake build system improvements for stable ABI wheel generation. (PR #222).
Version 1.3.0 (May 31, 2023)¶
This is a big release. The sections below cover added features, efficiency improvements, and miscellaneous fixes and improvements.
New features¶
nanobind now supports binding types that inherit from
std::enable_shared_from_this<T>
. See the advanced section on object ownership for more details. (PR #212).Added a type caster between Python
datetime
/timedelta
objects and C++std::chrono::duration
/std::chrono::time_point
, ported from pybind11. (PR #175).The
nb::ndarray<..>
class can now use the buffer protocol to receive and return arrays representing read-only memory. (PR #217).Added
nb::python_error::discard_as_unraisable()
as a wrapper aroundPyErr_WriteUnraisable()
. (PR #175).
Efficiency improvements:¶
Reduced the per-instance overhead of nanobind by 1 pointer and simplified the internal hash table types to crunch
libnanobind
. (commit de018d).Supplemental type data specified via
nb::supplement<T>()
is now stored directly within the type object instead of being referenced through an indirection. (commit d82ca9).Reduced the number of exception-related exports to further crunch
libnanobind
. (commit 763962).Reduced the size of nanobind type objects by 5 pointers. (PR #194, #195, and commit d82ca9).
Internal nanobind types (
nb_type
,nb_static_property
,nb_ndarray
) are now constructed on demand. This reduces the size of thelibnanobind
component in static (NB_STATIC
) builds when those features are not used. (commits 95e45a, 375083, and e033c8).Added a small function cache to improve code generation in limited API builds. (commit f0f4aa).
Refined compiler and linker flags across platforms to ensure compact binaries especially in
NB_STATIC
builds. (commit 5ead9f)nanobind enums now take advantage of supplemental data to improve the speed of object and name lookups. Note that this prevents use of
nb::supplement<T>()
with enums for other purposes. (PR #195).
Miscellaneous fixes and improvements¶
Use the new PEP-697 interface to access data in type objects when compiling stable ABI3 wheels. This improves forward compatibility (the Python team may at some point significantly refactor the layout and internals of type objects). (PR #211):
Added introspection attributes
__self__
and__func__
to nanobind bound methods, to make them more like regular Python bound methods. Fixed a bug wheresome_obj.method.__call__()
would behave differently thansome_obj.method()
. (PR #216).Updated the implementation of
nb::enum_
so it does not take advantage of any private nanobind type details. As a side effect, the constructnb::class_<T>(..., nb::is_enum(...))
is no longer permitted; usenb::enum_<T>(...)
instead. (PR #195).Added the
nb::type_slots_callback
class binding annotation, similar tonb::type_slots
but allowing more dynamic choices. (PR #195).nanobind type objects now treat attributes specially whose names begin with
@
. These attributes can be set once, but not rebound or deleted. This safeguard allows a borrowed reference to the attribute value to be safely stashed in the type supplement, allowing arbitrary Python data associated with the type to be accessed without a dictionary lookup while keeping this data visible to the garbage collector. (PR #195).Fixed surprising behavior in enumeration comparisons and arithmetic (PR #207):
Enum equality comparisons (
==
and!=
) now can only be true if both operands have the same enum type, or if one is an enum and the other is anint
. This resolves some confusing results and ensures that enumerators of different types have a distinct identity, which is important if they’re being put into the same set or used as keys in the same dictionary. All of the following were previously true but will now evaluate as false:FooEnum(1) == BarEnum(1)
FooEnum(1) == 1.2
FooEnum(1) == "1"
Enum ordering comparisons (
<
,<=
,>=
,>
) and arithmetic operations (when using theis_arithmetic
annotation) now require that any non-enum operand be a Python number (an object that defines__int__
,__float__
, and/or__index__
) and will avoid truncating non-integer operands to integers. Note that unlike with equality comparisons, ordering and arithmetic operations do still permit two operands that are enums of different types. Some examples of changed behavior:FooEnum(1) < 1.2
is now true (used to be false)FooEnum(2) * 1.5
is now 3.0 (used to be 2)FooEnum(3) - "2"
now raises an exception (used to be 1)
Enum comparisons and arithmetic operations with unsupported types now return
NotImplemented
rather than raising an exception. This means equality comparisons such assome_enum == None
will return unequal rather than failing; order comparisons such assome_enum < None
will still fail, but now with a more informative error.
ABI version 8.
Version 1.2.0 (April 24, 2023)¶
Improvements to the internal C++ → Python instance map data structure to improve performance and address type confusion when returning previously registered instances. (commit 716354, discussion 189).
Added up-to-date nanobind benchmarks on Linux including comparisons to Cython. (commit 834cf3 and 39e163).
Removed the superfluous
nb_enum
metaclass. (commit 9c1985).Fixed a corner case that prevented
nb::cast<char>
from working. (commit 9ae320).
Version 1.1.1 (April 6, 2023)¶
Added documentation on packaging and distributing nanobind modules. (commit 0715b2).
Made the conversion
handle::operator bool()
explicit. (PR #173).Support
nb::typed<..>
in return values. (PR #174).Tweaks to definitions in
nb_types.h
to improve compatibility with further C++ compilers (that said, there is no change about the official set of supported compilers). (commit b8bd10)
Version 1.1.0 (April 5, 2023)¶
Added
size
,shape_ptr
,stride_ptr
members to to thenb::ndarray<..>
class. (PR #161).Allow macros in
NB_MODULE(..)
name parameter. (PR #168).The
nb::ndarray<..>
interface is more tolerant when converting Python (PyTorch/NumPy/..) arrays with a size-0 dimension that have mismatched strides. (PR #162).Removed the
<anonymous>
label from docstrings of anonymous functions, which caused issues in MyPy. (PR #172).Fixed an issue in the propagation of return value policies that broke user-provided/custom policies in properties (PR #170).
The Eigen interface now converts 1x1 matrices to 1x1 NumPy arrays instead of scalars. (commit 445781).
The
nanobind
package now has a simple command line interface. (commit d5ccc8).
Version 1.0.0 (March 28, 2023)¶
Nanobind now has a logo. (commit b65d31).
Fixed a subtle issue involving function/method properties and the IPython command line interface. (PR #151).
Added a boolean type to the
nb::ndarray<..>
interface. (PR #150).Minor fixes and improvements.
Version 0.3.1 (March 8, 2023)¶
Added a type caster for
std::filesystem::path
. (PR #138 and commit 0b05cd).Fixed technical issues involving implicit conversions (commits 022935 and 5aefe3) and construction of type hierarchies with custom garbage collection hooks (commit 022935).
Re-enabled the ‘chained fixups’ linker optimization for recent macOS deployment targets. (commit 2f29ec).
Version 0.3.0 (March 8, 2023)¶
Botched release, replaced by 0.3.1 on the same day.
Version 0.2.0 (March 3, 2023)¶
Nanobind now features documentation on readthedocs.
The documentation process revealed a number of inconsistencies in the
class_<T>::def*
naming scheme. nanobind will from now on use the following shortened and more logical interface:Type
method
Methods & constructors
Fields
Properties
Static methods
Static fields
Static properties
Compatibility wrappers with deprecation warnings were also added to help port existing code. They will be removed when nanobind reaches version 1.0. (commits cb0dc3 and b5ed96)
The
nb::tensor<..>
class has been renamed tonb::ndarray<..>
, and it is now located in a different header file (nanobind/ndarray.h
). A compatibility wrappers with a deprecation warning was retained in the original header file. It will be removed when nanobind reaches version 1.0. (commit a6ab8b).Dropped the first two arguments of the
NB_OVERRIDE_*()
macros that turned out to be unnecessary in nanobind. (commit 22bc21).Added casters for dense matrix/array types from the Eigen library. (PR #120).
Added casters for sparse matrix/array types from the Eigen library. (PR #126).
Implemented
nb::bind_vector<T>()
analogous to similar functionality in pybind11. (commit f2df8a).Implemented
nb::bind_map<T>()
analogous to similar functionality in pybind11. (PR #114).nanobind now automatically downcasts polymorphic objects in return values analogous to pybind11. (commit cab96a).
nanobind now supports tag-based polymorphism. (commit 6ade94).
Updated tuple/list iterator to satisfy the
std::forward_iterator
concept. (PR #117).Fixed issues with non-writeable tensors in NumPy. (commit 25cc3c).
Removed use of some C++20 features from the codebase. This now makes it possible to use nanobind on Visual Studio 2017 and GCC 7.3.1 (used on RHEL 7). (PR #115).
Added the
nb::typed<...>
wrapper to override the type signature of an argument in a bound function in the generated docstring. (commit b3404c4).Added an
nb::implicit_convertible<A, B>()
function analogous to the one in pybind11. (commit aba4af).Updated
nb::make_*_iterator<..>()
so that it returns references of elements, not copies. (commit 8916f5).Changed the CMake build system so that the library component (
libnanobind
) is now compiled statically by default. (commit 8418a4).Switched shared library linking on macOS back to a two-level namespace. (commit fe4965).
Various minor fixes and improvements.
ABI version 7.
Version 0.1.0 (January 3, 2023)¶
Allow nanobind methods on non-nanobind) classes. (PR #104).
Fix dangling
tp_members
pointer in type initialization. (PR #99).Added a runtime setting to suppress leak warnings. (PR #109).
Added the ability to hash
nb::enum_<..>
instances (PR #106).Fixed the signature of
nb::enum_<..>::export_values()
. (commit 714d17).Double-check GIL status when performing reference counting operations in debug mode. (commit a1b245).
Fixed a reference leak that occurred when module initialization fails. (commit adfa9e).
Improved robustness of
nb::tensor<..>
caster. (commit 633672).Upgraded the internally used
tsl::robin_map<>
hash table to address a rare overflow issue discovered in this codebase. (commit 3b81b1).Various minor fixes and improvements.
ABI version 6.
Version 0.0.9 (Nov 23, 2022)¶
PyPy 7.3.10 or newer is now supported subject to certain limitations. (commits f935f93 and b343bbd).
Three changes that reduce the binary size and improve runtime performance of binding libraries. (commits 07b4e1fc, 9a803796, and cba4d285).
Fixed a reference leak in
python_error::what()
(commit 61393ad).Adopted a new policy for function type annotations. (commit c855c90).
Improved the effectiveness of link-time-optimization when building extension modules with the
NB_STATIC
flag. This leads to smaller binaries. (commit f64d2b9).Nanobind now relies on standard mechanisms to inherit the
tp_traverse
andtp_clear
type slots instead of trying to reimplement the underlying CPython logic (commit efa09a6b).Moved nanobind internal data structures from
builtins
to Python interpreter state dictionary. (issue #96, commit ca23da7).Various minor fixes and improvements.
Version 0.0.8 (Oct 27, 2022)¶
Caster for
std::array<..>
. (commit be34b16).Caster for
std::set<..>
andstd::unordered_set
(PR #87).Ported
nb::make[_key_,_value]_iterator()
from pybind11. (commit 34d0be1).Caster for untyped
void *
pointers. (commit 6455fff).Exploit move constructors in
nb::class_<T>::def_readwrite()
andnb::class_<T>::def_readwrite_static()
(PR #94).Redesign of the
std::function<>
caster to enable cyclic garbage collector traversal through inter-language callbacks (PR #95).New interface for specifying custom type slots during Python type construction. (commit 38ba18a).
Fixed potential undefined behavior related to
nb_func
garbage collection by Python’s cyclic garbage collector. (commit 662e1b9).Added a workaround for spurious reference leak warnings caused by other extension modules in conjunction with
typing.py
(commit 5e11e80).Various minor fixes and improvements.
ABI version 5.
Version 0.0.7 (Oct 14, 2022)¶
Fixed a regression involving function docstrings in
pydoc
. (commit 384f4a).
Version 0.0.6 (Oct 14, 2022)¶
Fixed undefined behavior that could lead to crashes when nanobind types were freed. (commit 39266e).
Refactored nanobind so that it works with
Py_LIMITED_API
(PR #37).Dynamic instance attributes (PR #38).
Intrusive pointer support (PR #43).
Byte string support (PR #62).
Casters for
std::variant<..>
andstd::optional<..>
(PR #67).Casters for
std::map<..>
andstd::unordered_map<..>
(PR #73).Caster for
std::string_view<..>
(PR #68).Custom exception support (commit 41b7da).
Register nanobind functions with Python’s cyclic garbage collector (PR #86).
Various minor fixes and improvements.
ABI version 3.
Version 0.0.5 (May 13, 2022)¶
Enumeration export.
Implicit number conversion for numpy scalars.
Various minor fixes and improvements.
Version 0.0.4 (May 13, 2022)¶
Botched release, replaced by 0.0.5 on the same day.
Version 0.0.3 (Apr 14, 2022)¶
DLPack support.
Iterators for various Python type wrappers.
Low-level interface to instance creation.
Docstring generation improvements.
Various minor fixes and improvements.
Version 0.0.2 (Mar 10, 2022)¶
Initial release of the nanobind codebase.
ABI version 1.
Version 0.0.1 (Feb 21, 2022)¶
Placeholder package on PyPI.