.. _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`.

.. 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>`_.
