pybind / pybind/pybind11

[BUG]: Tried to call pure virtual function

Open
#3,262 3 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
Problem description

Hi, I am trying to create a Python wrapper for a C++ class wrapped with pybind.
However, this class inherits from an abstract class and calling the foo method results in calling the abstract method instead.

The code was compiled with

g++ -O3 -Wall -shared -std=c++11 -fPIC $(python3 -m pybind11 --includes) test.cpp -o test$(python3-config --extension-suffix)

which results in

Traceback (most recent call last):
  File "/user/files/test.py", line 12, in <module>
    c.foo()
RuntimeError: Tried to call pure virtual function "parent::foo"

This behaviour feels quite strange; I would expect B::foo to be called.

Reproducible example code
#include <pybind11/pybind11.h>
namespace py = pybind11;

class A{

  public:
    A( int x ): m_x( x ){}
    virtual int foo() = 0;

  protected:
    int m_x;
};

class B: public A{

  public:
    B( int x ): A( x ){}
    virtual int foo(){ return m_x + 1; }
};

template <class parent = A>
class Py_A : public parent{

  public:
    using parent::parent;
    int foo() override{
      PYBIND11_OVERRIDE_PURE( int, parent, foo );
    }
};

PYBIND11_MODULE( test, m ){

  py::class_<A, Py_A<>>( m, "A" )
    .def(py::init<int>());

  py::class_<B, A, Py_A<B>>( m, "B" )
    .def(py::init<int>())
    .def("foo", &B::foo);
}
#!/usr/bin/env python3
from test import B

class C( B ):
  def __init__( self, *args, **kwargs ):
    super().__init__( *args, **kwargs )

if __name__ == "__main__":

  c = C( 1 )
  # RuntimeError: Tried to call pure virtual function "parent::foo"
  c.foo()

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 using the C++ example and Python script in the issue, built with the shown g++ command. Start by tracing the B::foo binding and PYBIND11_OVERRIDE_PURE behavior, then determine whether the observed dispatch should be corrected or documented; done means the example no longer raises unexpectedly or the expected behavior is clearly explained.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp, python
Domain
devtools
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.