How to define a Python metaclass with Boost.Python?

╄→尐↘猪︶ㄣ 提交于 2019-11-30 11:46:39

Okay this feels like a hack but it seems to work.

#include <boost/python.hpp>

class Meta
{
public:
    static boost::python::object
    newClass(boost::python::object cls, std::string name, boost::python::tuple bases, boost::python::dict attrs)
    {
        attrs["foo"] = "bar";
        boost::python::object types = boost::python::import("types");
        boost::python::object type = types.attr("TypeType");
        return type.attr("__new__")(type, name, bases, attrs);
    }
};

BOOST_PYTHON_MODULE(meta)
{
    boost::python::class_<Meta>("Meta")
    .def("__new__", &Meta::newClass)
    .staticmethod("__new__");
}

then in python

from meta import Meta

class Test(object):
    __metaclass__ = Meta

print Test, Test.foo
<class '__main__.Test'> bar

I tried some other things which didn't use the boost::python::object system but couldn't get anything that worked like this from the python side.

Although strictly speaking this isnt a metaclass as it doesnt inherit from type, but it behaves like one because type is used directly in the newClass function when calling new. If thats not a problem then it might be wise to change it from

return type.attr("__new__")(type, name, bases, attrs);

to

return type.attr("__new__")(cls.attr("__class__"), name, bases, attrs);

or something similar so Boost::Python::class is used instead of type.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!