Search code examples
c++python-3.xc++-chronopybind11

How to use chrono::microseconds with Pybind11?


The error boils down to this snippet.

#include <chrono>
#include <pybind11/chrono.h>
#include <pybind11/pybind11.h>

namespace chr = std::chrono;
namespace py = pybind11;

struct Time {
    chr::microseconds elapsed;

    Time(const chr::microseconds& elapsed) : elapsed(elapsed) {}
};

PYBIND11_MODULE(CppModule, m) {
    py::class_<Time>(m, "Time")
        .def(py::init<const chr::microseconds&>())
        .def("elapsed", &Time::elapsed);
}

When I try to build it, I get the following error.

'pybind11::cpp_function::cpp_function': no overloaded function takes 4 arguments

What should I do to read Time::elapsed on the Python side?


Solution

  • Method def binds functions. Methods def_readwrite and def_readonly bind fields.

    Time::elapsed is a field. That's why def cannot be used.

    PYBIND11_MODULE(CppModule, m) {
        py::class_<Time>(m, "Time")
            .def(py::init<const chr::microseconds&>())
            .def_readwrite("elapsed", &Time::elapsed);
    }
    

    Note that on Python side type chr::microseconds is converted to datetime.timedelta. To get the total number of microseconds divide it by 1 microsecond.

    import CppModule as m
    import datetime
    
    t = m.Time(datetime.timedelta(minutes=10, seconds=5))
    print(t.elapsed)
    print(t.elapsed // datetime.timedelta(microseconds=1))
    

    Output.

    0:10:05
    605000000