.. _custom_type_caster:

Custom type casters
===================

Some applications may prefer custom type casters that convert between existing
Python types and C++ types, similar to the ``list`` ↔ ``std::vector``
and ``dict`` ↔ ``std::map`` conversions which are built into pybind11.
Implementing custom type casters is fairly advanced usage.
While it is recommended to use the pybind11 API as much as possible, more complex examples may
require familiarity with the intricacies of the Python C API.
You can refer to the `Python/C API Reference Manual <https://docs.python.org/3/c-api/index.html>`_
for more information.

The following snippets demonstrate how this works for a very simple ``Point2D`` type.
We want this type to be convertible to C++ from Python types implementing the
``Sequence`` protocol and having two elements of type ``float``.
When returned from C++ to Python, it should be converted to a Python ``tuple[float, float]``.
For this type we could provide Python bindings for different arithmetic functions implemented
in C++ (here demonstrated by a simple ``negate`` function).

..
    PLEASE KEEP THE CODE BLOCKS IN SYNC WITH
        tests/test_docs_advanced_cast_custom.cpp
        tests/test_docs_advanced_cast_custom.py
    Ideally, change the test, run pre-commit (incl. clang-format),
    then copy the changed code back here.
    Also use TEST_SUBMODULE in tests, but PYBIND11_MODULE in docs.

.. code-block:: cpp

    namespace user_space {

    struct Point2D {
        double x;
        double y;
    };

    Point2D negate(const Point2D &point) { return Point2D{-point.x, -point.y}; }

    } // namespace user_space


The following Python snippet demonstrates the intended usage of ``negate`` from the Python side:

.. code-block:: python

    from my_math_module import docs_advanced_cast_custom as m

    point1 = [1.0, -1.0]
    point2 = m.negate(point1)
    assert point2 == (-1.0, 1.0)

To register the necessary conversion routines, it is necessary to add an
instantiation of the ``pybind11::detail::type_caster<T>`` template.
Although this is an implementation detail, adding an instantiation of this
type is explicitly allowed.

.. code-block:: cpp

    namespace pybind11 {
    namespace detail {

    template <>
    struct type_caster<user_space::Point2D> {
        // This macro inserts a lot of boilerplate code and sets the type hint.
        // `io_name` is used to specify different type hints for arguments and return values.
        // The signature of our negate function would then look like:
        // `negate(Sequence[float]) -> tuple[float, float]`
        PYBIND11_TYPE_CASTER(user_space::Point2D, io_name("Sequence[float]", "tuple[float, float]"));

        // C++ -> Python: convert `Point2D` to `tuple[float, float]`. The second and third arguments
        // are used to indicate the return value policy and parent object (for
        // return_value_policy::reference_internal) and are often ignored by custom casters.
        // The return value should reflect the type hint specified by the second argument of `io_name`.
        static handle
        cast(const user_space::Point2D &number, return_value_policy /*policy*/, handle /*parent*/) {
            return py::make_tuple(number.x, number.y).release();
        }

        // Python -> C++: convert a `PyObject` into a `Point2D` and return false upon failure. The
        // second argument indicates whether implicit conversions should be allowed.
        // The accepted types should reflect the type hint specified by the first argument of
        // `io_name`.
        bool load(handle src, bool /*convert*/) {
            // Check if handle is a Sequence
            if (!py::isinstance<py::sequence>(src)) {
                return false;
            }
            auto seq = py::reinterpret_borrow<py::sequence>(src);
            // Check if exactly two values are in the Sequence
            if (seq.size() != 2) {
                return false;
            }
            // Check if each element is either a float or an int
            for (auto item : seq) {
                if (!py::isinstance<py::float_>(item) && !py::isinstance<py::int_>(item)) {
                    return false;
                }
            }
            value.x = seq[0].cast<double>();
            value.y = seq[1].cast<double>();
            return true;
        }
    };

    } // namespace detail
    } // namespace pybind11

    // Bind the negate function
    PYBIND11_MODULE(docs_advanced_cast_custom, m, py::mod_gil_not_used()) { m.def("negate", user_space::negate); }

.. note::

    A ``type_caster<T>`` defined with ``PYBIND11_TYPE_CASTER(T, ...)`` requires
    that ``T`` is default-constructible (``value`` is first default constructed
    and then ``load()`` assigns to it).

.. note::
    For further information on the ``return_value_policy`` argument of ``cast`` refer to :ref:`return_value_policies`.
    To learn about the ``convert`` argument of ``load`` see :ref:`nonconverting_arguments`.

.. note::

    If a custom ``load()`` produces a non-owning view of storage owned by a
    Python object, and keeping that object alive is sufficient to keep the
    storage valid, register the owner (often ``src``) with
    ``pybind11::detail::loader_life_support::try_add_patient(owner)``. During a
    bound-function call, this keeps the owner alive until the call returns. With
    no active call frame, it returns ``false`` and the caller remains
    responsible for the lifetime.

    If ``load()`` instead creates a temporary Python object to own the view's
    storage, use the strict ``loader_life_support::add_patient(owner)``. Outside
    a bound-function call, it raises :class:`cast_error` rather than allowing a
    dangling view. Neither form permits C++ code to retain the view after the
    call without separate lifetime management. These ``detail`` helpers are
    intended only for type-caster implementations. See
    :ref:`string_view_lifetime` for a concrete example.

.. warning::

    When using custom type casters, it's important to declare them consistently
    in every compilation unit of the Python extension module to satisfy the C++ One Definition Rule
    (`ODR <https://en.cppreference.com/w/cpp/language/definition>`_). Otherwise,
    undefined behavior can ensue.

.. note::

    Using the type hint ``Sequence[float]`` signals to static type checkers, that not only tuples may be
    passed, but any type implementing the Sequence protocol, e.g., ``list[float]``.
    Unfortunately, that loses the length information ``tuple[float, float]`` provides.
    One way of still providing some length information in type hints is using ``typing.Annotated``, e.g.,
    ``Annotated[Sequence[float], 2]``, or further add libraries like
    `annotated-types <https://github.com/annotated-types/annotated-types>`_.
