Nanobind

Latest version: v2.5.0

Safety actively analyzes 707299 Python packages for vulnerabilities to keep your Python projects secure.

Scan your dependencies

Page 1 of 7

2.5.0

---------------------------

- Added :cpp:class:`nb::def_visitor\<..\> <def_visitor>`, which can be used to
define your own binding logic that operates on a :cpp:class:`nb::class_\<..\>
<class_>` when an instance of the visitor object is passed to
:cpp:func:`class_::def()`. This generalizes the mechanism used by
:cpp:class:`init`, :cpp:class:`new_`, etc, so that you can create binding
abstractions that "feel like" the built-in ones. (PR `884
<https://github.com/wjakob/nanobind/pull/884>`__)

- Added some special forms for :cpp:class:`nb::typed\<T, Ts...\> <typed>`
(PR `835 <https://github.com/wjakob/nanobind/pull/835>`__):

- ``nb::typed<nb::object, T>`` or ``nb::typed<nb::handle, T>`` produces
a parameter or return value that will be described like ``T`` in function
signatures but accepts any Python object at runtime.

- ``nb::typed<nb::callable, R(Args...)>`` produces a Python callable signature
``Callable[[Args...], R]``; similarly, ``nb::typed<nb::callable, R(...)>``
(with a literal ellipsis) produces the Python ``Callable[..., R]``.

- It is now possible to create Python subclasses of C++ classes that define
their constructor bindings using :cpp:struct:`nb::new_() <new_>`. Previously,
attempting to instantiate such a Python subclass would instead produce an
instance of the base C++ type. Note that it is still not possible to override
virtual methods in such a Python subclass, because the object returned by the
:cpp:struct:`new_() <new_>` constructor will generally not be an instance of
the alias/trampoline type. (PR `859
<https://github.com/wjakob/nanobind/pull/859>`__)

- Fixed the :cpp:class:`nb::int_ <int_>` constructor so that it casts to
an integer when invoked with a floating point argument.

- Multi-level inheritance (e.g., `A → B → C`) previously did not work on Python
3.12+ when a base class (e.g., ``A``) provided a trampoline implementation.
This is now fixed. (commit `92d9cb
<https://github.com/wjakob/nanobind/commit/92d9cb3d62b743a9eca2d9d9d8e5fb14a1e00a2a>`__).

- Fixed (benign) reference leads that could occur when ``std::shared_ptr<T>``
instances were still alive at interpreter shutdown time. (commit `fb8157
<https://github.com/wjakob/nanobind/commit/fb815762fdb8476cfd293e3717ca41c8bb890437>`__).

- The floating-point type caster now only performs value-changing narrowing
conversions during the implicit conversion phase. They can be entirely
avoided by passing the :cpp:func:`.noconvert() <arg::noconvert>` argument
annotation (PR `829 <https://github.com/wjakob/nanobind/pull/829>`__).

- The ``std::complex`` type caster now only performs value-changing narrowing
conversions during the implicit conversion phase. They can be entirely
avoided by passing the :cpp:func:`.noconvert() <arg::noconvert>` argument
annotation. Also, during the implicit conversion phase, if the Python object
is not a complex number object but has a ``__complex__()`` method, it will be
called (PR `854 <https://github.com/wjakob/nanobind/pull/854>`__).

- Fixed an overly strict check that could cause a function taking an
:cpp:class:`nb::ndarray\<...\> <ndarray>` to refuse specific types of
column-major input without implicit conversion. (PR `847
<https://github.com/wjakob/nanobind/pull/847>`__, commit `b95eb7
<https://github.com/wjakob/nanobind/commit/b95eb755b5a651a40562002be9ca8a4c6bf0acb9>`__).

Fixes for free-threaded builds
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

- Fixed a race condition in free-threaded extensions that could occur when
:cpp:func:`nb::make_iterator <make_iterator>` was concurrently used by
multiple threads (PR `832 <https://github.com/wjakob/nanobind/pull/832>`__).

- Fixed a race condition in free-threaded extensions that could occur when
multiple threads access the Python object associated with the same C++
instance, which does not exist yet and therefore must be created. (issue
`867 <https://github.com/wjakob/nanobind/issues/867>`__, PR `#887
<https://github.com/wjakob/nanobind/pull/887>`__).

- Removed double-checked locking patterns in accesses to internal data
structures to ensure correct free-threaded behavior on architectures with
weak memory ordering such as ARM (PR `819
<https://github.com/wjakob/nanobind/pull/819>`__).

2.4.0

---------------------------

- Added a function annotation :cpp:class:`nb::call_policy\<Policy\>()
<call_policy>` which supports custom function wrapping logic,
calling ``Policy::precall()`` before the bound function and
``Policy::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 <https://github.com/wjakob/nanobind/pull/767>`__)

- :cpp:func:`nb::make_iterator <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
<https://github.com/wjakob/nanobind/pull/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 where
``std::variant<U, T>`` might cast a Python object wrapping a ``T`` to a ``U`` if
there is an implicit conversion available from ``T`` to ``U``.
(issue `769 <https://github.com/wjakob/nanobind/issues/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 <https://github.com/wjakob/nanobind/issues/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, after ``a += b``, ``a`` would be replaced with a copy.
(PR `803 <https://github.com/wjakob/nanobind/pull/803>`__)

- Added an overload to :cpp:func:`nb::isinstance <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 <https://github.com/wjakob/nanobind/pull/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 <https://github.com/wjakob/nanobind/pull/806>`__).

- Other minor fixes and improvements. (PRs `771
<https://github.com/wjakob/nanobind/pull/771>`__, `#772
<https://github.com/wjakob/nanobind/pull/772>`__, `#748
<https://github.com/wjakob/nanobind/pull/748>`__, and `#753
<https://github.com/wjakob/nanobind/pull/753>`__)

2.3.0

-------------

There is no version 2.3.0 due to a deployment mishap.

2.2.0

-------------------------------

- nanobind can now target `free-threaded Python
<https://py-free-threading.github.io>`__, which replaces the `Global
Interpreter Lock (GIL)
<https://en.wikipedia.org/wiki/Global_interpreter_lock>`__ with a
fine-grained locking scheme (see `PEP 703
<https://peps.python.org/pep-0703/>`__) to better leverage multi-core
parallelism. A :ref:`separate documentation page <free-threaded>` explains this in
detail (PRs `695 <https://github.com/wjakob/nanobind/pull/695>`__, `#720
<https://github.com/wjakob/nanobind/pull/720>`__)

- nanobind has always used `PEP 590 vector calls
<https://www.python.org/dev/peps/pep-0590>`__ 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 <https://github.com/wjakob/nanobind/pull/706>`__, commits
`e24d7f <https://github.com/wjakob/nanobind/commit/e24d7f3434a6bbcc33cd8965632dc47f943fb2f8>`__,
`0acecb <https://github.com/wjakob/nanobind/commit/0acecb474874f286119dce2b97b84142b6ada1a8>`__,
`77f910 <https://github.com/wjakob/nanobind/commit/77f910f2a92c88f2c5512f3c375b4fe94369558e>`__,
`2c96d5 <https://github.com/wjakob/nanobind/commit/2c96d5ae2fdbca030dccb1d01c457c7c5df29a0d>`__).

* A new :cpp:class:`nb::is_flag() <is_flag>` annotation in
:cpp:class:`nb::enum_\<T\>() <enum_>` produces enumeration
bindings deriving from :py:class:`enum.Flag`, which enables
bit-wise combination using compatible operators (``&``, ``|``,
``^``, and ``~``). Further combining the annotation with
:cpp:class:`nb::is_arithmetic() <is_flag>` creates
enumerations deriving from :py:class:`enum.IntFlag`. (PRs
`599 <https://github.com/wjakob/nanobind/pull/599>`__,
`688 <https://github.com/wjakob/nanobind/pull/688>`__,
`688 <https://github.com/wjakob/nanobind/pull/688>`__,
`727 <https://github.com/wjakob/nanobind/pull/727>`__,
`732 <https://github.com/wjakob/nanobind/pull/732>`__)

* A refactor of :cpp:class:`nb::ndarray\<...\> <ndarray>` was an opportunity to
realize three usability improvements:

1. The constructor used to return new nd-arrays from C++ now considers
all template arguments:

- **Memory order**: :cpp:class:`c_contig`, :cpp:class:`f_contig`.
- **Shape**: :cpp:class:`nb::shape\<3, 4, 5\> <shape>`, etc.
- **Device type**: :cpp:class:`nb::device::cpu <device::cpu>`,
:cpp:class:`nb::device::cuda <device::cuda>`, etc.
- **Framework**: :cpp:class:`nb::numpy <numpy>`,
:cpp:class:`nb::pytorch <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:

.. code-block:: cpp

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);

2. A new nd-array :cpp:func:`.cast() <ndarray::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 :ref:`return temporaries (e.g. stack-allocated
memory) <ndarray-temporaries>` from functions.

3. Added a new and more general mechanism ``nanobind::detail::dtype_traits<T>``
to declare custom ndarray data types like ``float16`` or ``bfloat16``. The old
interface (``nanobind::ndarray_traits<T>``) still exists but is deprecated
and will be removed in the next major release. See the :ref:`documentation
<ndarray-nonstandard>` for details.

There are two minor but potentially breaking changes:

1. The nd-array type caster now interprets the
:cpp:enumerator:`nb::rv_policy::automatic_reference
<rv_policy::automatic_reference>` return value policy analogously to the
:cpp:enumerator:`nb::rv_policy::automatic <rv_policy::automatic>`, which
means that it references a memory region when the user specifies an
``owner``, and it otherwise copies. This makes it safe to use the
:cpp:func:`nb::cast() <cast>` and :cpp:func:`nb::ndarray::cast()
<ndarray::cast>` functions that use this policy as a default.

2. The :cpp:class:`nb::any_contig <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
<https://github.com/wjakob/nanobind/pull/721>`__, For further details on the
nd-array changes, see PR `742
<https://github.com/wjakob/nanobind/pull/742>`__, and commit `4647ef
<https://github.com/wjakob/nanobind/commit/4647efcc45d96e530d41a3461cd9727656bc2ca3>`__.

- The NVIDIA CUDA compiler (``nvcc``) is now explicitly supported and included
in nanobind's CI test suite (PR `710
<https://github.com/wjakob/nanobind/pull/710>`__).

* Added support for return value policy customization to the type casters of
``Eigen::Ref<...>`` and ``Eigen::Map<...>`` (commit `67316e
<https://github.com/wjakob/nanobind/commit/67316eb88955a15e8e89a57ce9a53d8d66263287>`__).

* Added the :cpp:class:`bytearray` wrapper type. (PR `654
<https://github.com/wjakob/nanobind/pull/654>`__)

* The :cpp:class:`nb::ellipsis <ellipsis>` type now renders as ``...`` when
used in :cpp:class:`nb::typed\<...\> <typed>` (PR `705
<https://github.com/wjakob/nanobind/pull/705>`__).

* The :cpp:class:`nb::sig("...") <sig>` annotation now supports `inline type
parameter lists
<https://docs.python.org/3/reference/compound_stmts.html#type-params>`__ such
as ``def first[T](l: Sequence[T]) -> T`` (PR `704
<https://github.com/wjakob/nanobind/pull/704>`__).

* Fixed implicit conversion of complex nd-arrays. (issue `709
<https://github.com/wjakob/nanobind/issues/709>`__)

* Casting via :cpp:func:`nb::cast <cast>` can now specify an owner object for
use with the :cpp:enumerator:`nb::rv_policy::reference_internal
<rv_policy::reference_internal>` return value policy (PR `667
<https://github.com/wjakob/nanobind/pull/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 <https://github.com/wjakob/nanobind/pull/675>`__)

* ABI version 15.

* Minor fixes and improvements (PRs
`703 <https://github.com/wjakob/nanobind/pull/703>`__,
`724 <https://github.com/wjakob/nanobind/pull/724>`__,
`723 <https://github.com/wjakob/nanobind/pull/723>`__,
`722 <https://github.com/wjakob/nanobind/pull/722>`__,
`715 <https://github.com/wjakob/nanobind/pull/715>`__,
`696 <https://github.com/wjakob/nanobind/pull/696>`__,
`693 <https://github.com/wjakob/nanobind/pull/693>`__,
commit `75d259 <https://github.com/wjakob/nanobind/commit/75d259c7c16db9586e5cd3aa4715e09a25e76d83>`__).

2.1.0

----------------------------

* 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
<https://github.com/wjakob/nanobind/issues/613>`__, commit `f2438b
<https://github.com/wjakob/nanobind/commit/f2438bb73a1673e4ad9d0c84d353a88cf54e55bf>`__).

* nanobind no longer prevents casting to a C++ container of pointers ``T*``
where ``T`` is a type with a user-defined type caster if the caster seems to
operate by extracting a ``T*`` from the Python object rather than a ``T``.
This change was prompted by discussion `605
<https://github.com/wjakob/nanobind/discussions/605>`__.

* Switched nanobind wheel generation from `setuptools
<https://github.com/pypa/setuptools>`__ to `scikit-build-core
<https://github.com/scikit-build/scikit-build-core>`__ (PR `#618
<https://github.com/wjakob/nanobind/discussions/618>`__).

* Improved handling of ``const``-ness in :cpp:class:`nb::ndarray <ndarray>` (PR
`491 <https://github.com/wjakob/nanobind/discussions/491>`__).

* Keyword argument annotations are now properly supported with
:cpp:struct:`nb::new_ <new_>`, passed in the same way they would be with
:cpp:struct:`nb::init <init>`. (issue `668
<https://github.com/wjakob/nanobind/issues/668>`__)

* Ability to use :cpp:func:`nb::cast <cast>` to create object with the
:cpp:enumerator:`nb::rv_policy::reference_internal
<rv_policy::reference_internal>` return value policy (PR `667
<https://github.com/wjakob/nanobind/pull/667>`__).

* Enable ``char`` type caster to produce ``'\0'`` (PR `661
<https://github.com/wjakob/nanobind/pull/661>`__).

* Added ``.def_static()`` member to :cpp:class:`nb::enum_ <enum_>`, which had
been lost in a redesign of the enumeration implementation in nanobind version
2.0.0. (commit `38990e
<https://github.com/wjakob/nanobind/commit/38990ea33bb499bcc23607147555bf5bb00dcf62>`__).

* Fixes for two minor sources of memory leaks (PR
`595 <https://github.com/wjakob/nanobind/pull/595>`__,
`647 <https://github.com/wjakob/nanobind/pull/647>`__).

* The nd-array wrapper :cpp:class:`nb::ndarray <ndarray>` now properly handles
CuPy arrays (`594 <https://github.com/wjakob/nanobind/pull/594>`__).

* Added :cpp:func:`nb::hash() <hash>`, a wrapper for the Python ``hash()``
function (commit `91fafa5
<https://github.com/wjakob/nanobind/commit/01fafa5b9e1de0f1ab2a9d108cd0fce20ab9568f>`__).

* Various minor ``stubgen`` fixes (PRs
`667 <https://github.com/wjakob/nanobind/pull/667>`__,
`658 <https://github.com/wjakob/nanobind/pull/658>`__,
`632 <https://github.com/wjakob/nanobind/pull/632>`__,
`620 <https://github.com/wjakob/nanobind/pull/620>`__,
`592 <https://github.com/wjakob/nanobind/pull/592>`__).

2.0.0

----------------------------

The 2.0.0 release of nanobind is entirely dedicated to *types* [f1]_! 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 <https://github.com/python/mypy>`__, `PyRight
<https://github.com/microsoft/pyright>`__, `PyType
<https://github.com/google/pytype>`__, and editors with interactive
autocompletion like `Visual Studio Code <https://code.visualstudio.com>`__,
`PyCharm <https://www.jetbrains.com/pycharm/>`__, and many other `LSP
<https://en.wikipedia.org/wiki/Language_Server_Protocol>`__-compatible IDEs.

This required work on three fronts:

1. **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
<https://typing.readthedocs.io/en/latest/source/stubs.html>`__ 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 :ref:`new documentation section <stubs>`.

2. **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 as ``collections.abc.Sequence[T]`` in stubs when it is
used as an *input*, and ``list[T]`` when it is used as part of a return
value. The :cpp:func:`nb::make_*_iterator() <make_iterator>` family of
functions return typed iterators, etc.

3. **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]``). The :cpp:class:`nb::typed\<T, Ts...\> <typed>` wrapper
enables such parameterization within C++ (for example, the
``int``-specialized list would be written as ``nb::typed<nb::list,
int>``). :ref:`Read more <typing_generics_parameterizing>`.

* The opposite is also possible: passing :cpp:class:`nb::is_generic()
<is_generic>` to the class binding constructor

.. code-block:: cpp

nb::class_<MyType>(m, "MyType", nb::is_generic())

produces a *generic* type that can be parameterized in Python (e.g.
``MyType[int]``). :ref:`Read more <typing_generics_creating>`.

* The :cpp:class:`nb::sig <sig>` annotation overrides the
signature of a function or method, e.g.:

.. code-block:: cpp

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. :ref:`Read more <typing_signature_functions>`.

* The :cpp:class:`nb::sig <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.

.. code-block:: cpp

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. :ref:`Read more <typing_signature_classes>`.

* The :cpp:struct:`nb::for_setter <for_setter>` and
:cpp:struct:`nb::for_getter <for_getter>` annotations enable passing
function binding annotations (e.g., signature overrides) specifically to
the setter or the getter part of a property.

* The :cpp:class:`nb::arg("name") <arg>` argument annotation (and
``"name"_a`` shorthand) now have a :cpp:func:`.sig("signature")
<arg::sig>` 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 :ref:`pattern files
<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 <http://semver.org>`__. The following changes are
noteworthy:

* The :cpp:class:`nb::enum_\<T\>() <enum_>` binding declaration is now a
wrapper that creates either a :py:class:`enum.Enum` or :py:class:`enum.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 (:py:class:`enum.IntEnum`-derived) enumerations. Replace
``int(my_enum_entry)`` with ``my_enum_entry.value`` to work around the issue.

* The :cpp:func:`nb::bind_vector\<T\>() <bind_vector>` and
:cpp:func:`nb::bind_map\<T\>() <bind_map>` 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 :cpp:func:`nb::bind_vector\<T\>()
<bind_vector>` discusses the issue at length and presents alternative
solutions.

* The functions :cpp:func:`nb::make_iterator() <make_iterator>`,
:cpp:func:`nb::make_value_iterator() <make_value_iterator>` and
:cpp:func:`nb::make_key_iterator() <make_key_iterator>` suffer from the same
issue as :cpp:func:`nb::bind_vector() <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 :cpp:func:`nb::make_iterator()
<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 unconstrained
:cpp:class:`nb::ndarray <ndarray>` axis was removed. This name was given to a
new wrapper type :cpp:class:`nb::any` indicating ``typing.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>``).

* :ref:`Keyword-only arguments <kw_only>` are now supported, and can be
indicated using the new :cpp:struct:`nb::kw_only() <kw_only>` function
annotation. (PR `448 <https://github.com/wjakob/nanobind/pull/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
:ref:`customizing Python object creation <custom_new>` for more details.
(PR `473 <https://github.com/wjakob/nanobind/pull/473>`__).

* When binding methods on a class ``T``, nanobind will now produce a Python
function that expects a self argument of type ``T``. Previously, it would
use the type of the member pointer to determine the Python function
signature, which could be a base of ``T``, which would create problems
if nanobind did not know about that base.
(PR `471 <https://github.com/wjakob/nanobind/pull/471>`__).

* nanobind can now handle keyword arguments that are not interned, which avoids
spurious ``TypeError`` exceptions in constructs like
``fn(**pickle.loads(...))``. The speed of normal function calls (which
generally do have interned keyword arguments) should be unaffected. (PR `469
<https://github.com/wjakob/nanobind/pull/469>`__).

* The ``owner=nb::handle()`` default value of the :cpp:class:`nb::ndarray
<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
<https://github.com/wjakob/nanobind/pull/549>`__).

* Type casters that implement custom cast operators must now define a
member function template ``can_cast<T>()``, which returns false if
``operator cast_t<T>()`` would raise an exception and true otherwise.
``can_cast<T>()`` will be called only after a successful call to
``from_python()``, and might not be called at all if the caller of
``operator cast_t<T>()`` can cope with a raised exception.
(Users of the ``NB_TYPE_CASTER()`` convenience macro need not worry
about this; it produces cast operators that never raise exceptions,
and therefore provides a ``can_cast<T>()`` that always returns true.)

* Many type casters for container types (``std::vector<T>``,
``std::optional<T>``, etc) implement their ``from_python()`` methods
by delegating to another, "inner" type caster (``T`` in these examples)
that is allocated on the stack inside ``from_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's
``from_python`` method) in ``flags_for_local_caster<T>()`` before
passing them to ``inner_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 verify
``inner_caster.template can_cast<T>()`` before you execute
``inner_caster.operator cast_t<T>()``. A failure of
``can_cast()`` should be treated the same as a failure of
``from_python()``. This avoids the possibility of an exception
being raised through the noexcept ``load_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, but ``can_cast<T>()`` now handles that problem more generally.

* ABI version 14.

.. rubric:: Footnote

.. [f1] The author of this library had somewhat of a revelation after
switching to a `new editor <https://neovim.io>`__ and experiencing the
benefits of interactive Python code completion and type checking for the
first time. This experience also showed how nanobind-based extension were
previously a second-class citizen in this typed world, prompting the changes
in this release.

Page 1 of 7

© 2025 Safety CLI Cybersecurity Inc. All Rights Reserved.