pybind / pybind/pybind11

[BUG]: Segfault when getting repr of enum which hasn't been bound

Open
#5,101 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

triage
Dominant language
C++
Stars
18k
Forks
2.3k
Avg merge
5d 17h
Merged PRs (30d)
10

Description

Required prerequisites
What version (or hash if on master) of pybind11 are you using?

2.11.1

Problem description

When attempting to get the repr of a C++ enum which hasn't been bound, a segfault occurs:

Thread 1 "python3" received signal SIGSEGV, Segmentation fault.
0x00005555556b1e76 in PyObject_GetAttrString (v=0x0, name=0x7ffff6dcd847 "__repr__") at ../Objects/object.c:810
810     ../Objects/object.c: No such file or directory.
(gdb) bt
#0  0x00005555556b1e76 in PyObject_GetAttrString (v=0x0, name=0x7ffff6dcd847 "__repr__") at ../Objects/object.c:810
#1  0x00007ffff6d7e25b in pybind11::getattr (obj=..., name=0x7ffff6dcd847 "__repr__") at /home/myuser/mylib/.venv/include/pybind11/pytypes.h:882
#2  0x00007ffff6d7e92d in pybind11::detail::accessor_policies::str_attr::get (obj=..., key=0x7ffff6dcd847 "__repr__") at /home/myuser/mylib/.venv/include/pybind11/pytypes.h:1055
#3  0x00007ffff6da389f in pybind11::detail::accessor<pybind11::detail::accessor_policies::str_attr>::get_cache (this=0x7fffffff8ae0) at /home/myuser/mylib/.venv/include/pybind11/pytypes.h:1034
#4  0x00007ffff6d9d9e6 in pybind11::detail::accessor<pybind11::detail::accessor_policies::str_attr>::ptr (this=0x7fffffff8ae0) at /home/myuser/mylib/.venv/include/pybind11/pytypes.h:1022
#5  0x00007ffff6da0659 in pybind11::detail::object_api<pybind11::detail::accessor<pybind11::detail::accessor_policies::str_attr> >::operator()<(pybind11::return_value_policy)1> (this=0x7fffffff8ae0)
    at /home/myuser/mylib/.venv/include/pybind11/cast.h:1672
#6  0x00007ffff6da081d in get_repr<TestEnum> (obj=@0x7fffffff8b44: TestEnum::One) at /home/myuser/mylib/cpp/agc/py_wrap/agc_wrap.cpp:14

It makes sense that pybind11 can't execute this code without the binding for the enum, but typically pybind11 is pretty good at providing clear error messages when one has forgotten to bind a type. I was surprised that pybind11::cast will happily cast an object which has not been bound.

It would be helpful if pybind11 could raise an exception/print an error message when interacting with an enum which hasn't been bound, rather than just segfaulting.

Note: I have not explored the limits of this case (if its specific to enums, if its a problem with pybind11::cast or some other part of the system, etc), but found this particular behavior very surprising.

Reproducible example code
wrapper:

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

namespace py = pybind11;
enum class TestEnum
{
    One,
    Two,
    Three,
};

template <class T> 
std::string get_repr(const T& obj){
    return pybind11::cast<std::string>(pybind11::cast(obj).attr("__repr__")());
}

std::string get_test_enum_repr(){
    return get_repr(TestEnum::One);
}

PYBIND11_MODULE(_agc, m)
{

    // Uncomment this and everything works as expected
    // py::enum_<TestEnum>(m, "TestEnum")
    //     .value("One", TestEnum::One)
    //     .value("Two", TestEnum::Two)
    //     .value("Three", TestEnum::Three);

    m.def("get_test_enum_repr", &get_test_enum_repr);
}

test code:

print(agc.get_test_enum_repr())


### Is this a regression? Put the last known working version here if it is.

Not a regression

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the failure with the provided _agc module and get_test_enum_repr example, then inspect pybind11/cast.h and pybind11/pytypes.h along the shown cast and attribute-access paths. Done means an unbound enum no longer segfaults and instead produces the requested exception or clear error message.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp, python
Domain
api, backend-api-design
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.