Open
Description
Problem description
Serialization of objects using protocol 0 (original "human-readable" protocol) does not work anymore from Python 3.9.
Reproducible example code
core.cpp
#include <pybind11/pybind11.h>
class Foo {
public:
explicit Foo() {}
inline auto getstate() const { return pybind11::tuple(); }
inline static Foo setstate(pybind11::tuple state) {
if (state.size() != 0) throw std::runtime_error("Invalid state!");
return Foo();
}
};
auto init_module(pybind11::module& m) {
pybind11::class_<Foo>(m, "Foo")
.def(pybind11::init<>())
.def(pybind11::pickle(
[](const Foo& f) { return f.getstate(); },
[](pybind11::tuple state) { return Foo::setstate(state); }));
}
PYBIND11_MODULE(core, m) { init_module(m); }
compilation
clang++ -O3 -Wall -shared -std=c++17 -fPIC $(python3 -m pybind11 --includes) core.cpp -o core$(python3-config --extension-suffix)
foo.py
import pickle
import core
def main():
instance = core.Foo()
# It always works.
result = pickle.dumps(instance, protocol=-1)
# Starting with python 3.9, the protocol=0 throws the error:
# terminate called after throwing an instance of 'std::runtime_error'
# what(): instance allocation failed: new instance has no pybind11-registered base types
# Aborted (core dumped)
result = pickle.dumps(instance, protocol=0)
if __name__ == '__main__':
main()