wlav / cppyy

Other
391 stars 40 forks source link

Overriding base class pure virtual method as a python lambda function gives an error. #132

Closed Fancyapplebee closed 1 year ago

Fancyapplebee commented 1 year ago

Overriding base class pure virtual method as a python lambda function gives an error. However, if we change the python lambda to a regular python method, it works.

import cppyy

cppyy.cppdef(
r'''
struct AbstractTest
{
    virtual ~AbstractTest(){};
    AbstractTest(std::string name){}
    virtual double ExpLevelFunc(double) = 0;
    double someFunc()
    {
        return ExpLevelFunc(1.1);
    }
};
'''
)

from cppyy.gbl import AbstractTest

class ConcreteTest(AbstractTest):
    def __init__(self, name):
        super().__init__(name)
        self.ExpLevelFunc = lambda x: x

x = ConcreteTest("hi")
print(x.someFunc())
wlav commented 1 year ago

edited as I see that the intend of that lambda was different; code below works

It's not the lambda that's the issue, but the order of creation. When ConcreteTest is created, it is still abstract b/c it's missing ExpLevelFunc, so it can not be instantiated and super().__init__(name) will therefore fail (I appreciate that the error message isn't particularly clear).

To make it work, use a placeholder as a promise that you'll implement the method:

import cppyy

cppyy.cppdef(
r'''
struct AbstractTest
{
    virtual ~AbstractTest(){};
    AbstractTest(std::string name){}
    virtual double ExpLevelFunc(double) = 0;
    double someFunc()
    {
        return ExpLevelFunc(1.1);
    }
};
'''
)

from cppyy.gbl import AbstractTest

class ConcreteTest(AbstractTest):
    def __init__(self, name="aap"):
        super().__init__(name)
        self.ExpLevelFunc = lambda x: x

    def ExpLevelFunc(self, d):
        raise NotImplementedError()

x = ConcreteTest("hi")
print(x.someFunc())
wlav commented 1 year ago

I appreciate that the error message isn't particularly clear

actually no, the error does state clearly "cannot instantiate abstract class", pointing to the __init__ so I think it's fine.

wlav commented 1 year ago

Closing as presumed clarified. Feel free to re-open or start a new issue if there are further questions.