Reputation: 1496
How do I access the boost::python::class_ object that's been registered for a given C++ class? I'm importing a boost::python module which defines a wrapper for boost::property_tree::ptree, but I would like to add additional methods to this wrapper definition. When I attempt to create a new wrapper, Boost Python complains that a handler has already been declared, and ignores my new definition.
Any ideas?
Upvotes: 2
Views: 667
Reputation: 332
I had a similar question, with one difference: As the class export definition was in my own code, I was able to change the part where the boost::python::class_
was first called.
If this is also possible in your case, a solution might look like this:
static auto ptree_class_ = boost::python::class_< ptree > ( "ptree" );
// somewhere later in your code:
ptree_class_.def("contains", &ptree__contains);
This eliminates the need for extra Python code -- all is done in C++.
Here you can find my original solution: https://stackoverflow.com/a/30622038/4184258
Upvotes: 0
Reputation: 1496
Following the suggestion of daramarak, as well as the Boost Python tutorial Extending Wrapped Objects In Python, I extended the class from within python. Python, and thus Boost::Python make little distinction between bound member functions and functions whose first argument is an object reference (or pointer). Thus you can define a function in C++ like so:
bool ptree__contains(boost::property_tree::ptree* self, const std::string& key) {
return self->find(key)!=self->not_found();
}
And then augment the imported class in Python like so:
from other_module import ptree
from my_module import ptree__contains
# The __contains__ method is a special api function
# that enables "foo in bar" boolean test statements
ptree.__contains__ = ptree__contains
test_ptree = ptree()
test_ptree.put("follow.the.yellow.brick.road", "OZ!")
print "follow.the.yellow.brick.road" in test_ptree
# > true
I added my augmentation code to the __init__.py
of my module, such that any imports of my module would automatically add the desired methods to the external object. I defined a function which modified the class, called this function, and then deleted it to clean up my namespace. Alternatively, you can exclude this function from your __all__
listing to keep it from being exported by from module import *
statements. Works like a charm! Thanks again to daramarak.
Upvotes: 3