Skip to content

[BUG]: make_iterator causes runtime error in second scoped_interpreter #3776

Description

@jasjuang

Required prerequisites

Problem description

This issue is similar to #2101, the reported minimal example problem in #2101 is fixed in the latest master because of #3744. However, the below minimal example will produce the error

1
2
3
terminate called after throwing an instance of 'pybind11::error_already_set'
what(): RuntimeError: instance allocation failed: new instance has no pybind11-registered base types
At:
<string>(4): <module>
Aborted (core dumped)

I can reproduce this problem in Ubuntu and macOS.

The real use case is that each gtest TEST block will have its own py::scoped_interpreter, and this bug is preventing me from writing for i in testclass: more than once, but I would like to write for i in testclass: in multiple different TEST blocks.

Reproducible example code

CMakeLists.txt

cmake_minimum_required(VERSION 3.20)
project(pybindsample)
set(pybind11_DIR "/home/jasjuang/install/share/cmake/pybind11")
find_package(pybind11 REQUIRED)
pybind11_add_module(${PROJECT_NAME} pybindsample.cpp)
target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_17)
add_executable(pybindsample_test pybindsample_test.cpp)
target_link_libraries(pybindsample_test pybind11::module pybind11::embed)

pybindsample.cpp

#include "pybind11/pybind11.h"
#include "pybind11/stl.h"
namespace py = pybind11;
class TestClass {
public:
TestClass() = default;
std::vector<int>::iterator begin() noexcept { return vec.begin(); }
std::vector<int>::iterator end() noexcept { return vec.end(); }
private:
std::vector<int> vec = {1, 2, 3};
};
PYBIND11_MODULE(pybindsample, m) {
py::class_<TestClass>(m, "TestClass")
.def(py::init<>())
.def(
"__iter__",
[](TestClass &t) { return py::make_iterator(t.begin(), t.end()); },
py::keep_alive<0, 1>());
}

pybindsample_test.cpp

#include "pybind11/embed.h"
#include "pybind11/pybind11.h"
#include "pybind11/stl.h"
namespace py = pybind11;
int main() {
{
py::scoped_interpreter g;
py::eval<py::eval_statements>("import pybindsample\n"
"testclass=pybindsample.TestClass()\n"
"for i in testclass:\n"
" print(i)\n");
}
{
py::scoped_interpreter g;
py::eval<py::eval_statements>("import pybindsample\n"
"testclass=pybindsample.TestClass()\n"
"for i in testclass:\n"
" print(i)\n");
}
return 0;
}

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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