Skip to content

[BUG] pickleable base C++ classes can incur object slicing if derived typeid is not registered with pybind11 #3062

Open
@EricCousineau-TRI

Description

@EricCousineau-TRI

Issue description

Context: #2972 (comment)

If you have C++ base class that is exposed to pybind11, but then you have a derived class that is not exposed to pybind11, then you will encounter object slicing (wikipedia) via a pickle -> unpickle round trip.
Slicing may mean that the unpickled object has the wrong vtable, data, etc.

Reproducible example code

master...EricCousineau-TRI:issue-3062 (derived from fixes in #2972)
commit: 7ce1ad0

Upon running the test:

$ make pytest
...
    def test_roundtrip_simple_cpp_derived():
        p = m.make_SimpleCppDerivedAsBase()
        p.num = 404
        assert m.get_value_via_vtable_cpp(p) == 10
...
        data = pickle.dumps(p, pickle.HIGHEST_PROTOCOL)
        p2 = pickle.loads(data)
        assert isinstance(p2, m.SimpleBase)
        assert p2.num == 404
>       assert m.get_value_via_vtable_cpp(p2) == 10
E       assert 1 == 10  # Egad! Error!

\cc @rwgk @YannickJadoul @elkhrt

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions