|
Boost : |
Subject: [boost] boost::python feature request: unique_ptr, interfaces and factory functions
From: Maxim Yegorushkin (maxim.yegorushkin_at_[hidden])
Date: 2012-10-20 10:43:08
Hi Boost,
I am using boost::python to expose a C++ API into Python. The class I
would like to export is:
struct Subscriber {
virtual ~Subscriber() = 0;
static std::unique_ptr<Subscriber> create();
};
It's an interface with a factory function returning a std::unique_ptr<>.
I would like to be able to export it in the following manner:
BOOST_PYTHON_MODULE(pub_sub) {
boost::python::class_<
Subscriber
, std::unique_ptr<Subscriber>
, boost::noncopyable
>("Subscriber")
.def(boost::python::init<>, Subscriber::create)
;
;
}
I.e., the python wrapper would hold a std::unique_ptr<Subscriber> and
use Subscriber::create() factory function as a constructor for Python
Subscriber class.
The above code doesn't compile with boost-1.51.0 for two reasons:
* std::unique_ptr<> is not supported by boost::python. On the other
hand, std::auto_ptr<> is.
* The factory function can't be used used as a Python object
constructor.
I thought there could be a way to specialize certain boost::python
traits/metaclasses to make it work with std::unique_ptr<> and factory
functions as constructors, but couldn't figure it out.
The workaround I managed to get working is:
std::auto_ptr<Subscriber> createSubscriber() {
return std::auto_ptr<Subscriber>(Subscriber::create().release());
}
BOOST_PYTHON_MODULE(pub_sub) {
// Expose the class.
boost::python::class_<
Subscriber
, std::auto_ptr<Subscriber>
, boost::noncopyable
>("Subscriber_", boost::python::no_init)
;
;
// Expose its factory function.
boost::python::def("Subscriber", createSubscriber);
}
I.e., std::unique_ptr<> gets replaced with std::auto_ptr<>, the Python
class is renamed to Subscriber_ and the factory function gets exported
as Subscriber allowing for Python syntax:
import pub_sub
s = pub_sub.Subscriber()
# however
assert isinstance(s, pub_sub.Subscriber) # fails
assert isinstance(s, pub_sub.Subscriber_) # succeeds
So, I was wondering if there are ways to make my original Python class
export syntax work?
-- Maxim
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk