diff --git a/src/gen_call.py b/src/gen_call.py index dd178648..f609c0ae 100644 --- a/src/gen_call.py +++ b/src/gen_call.py @@ -36,7 +36,7 @@ def gen_call(member_function_args, free_function_args = None): return (header % (member_function_args, free_function_args) + gen_functions( '''template -PyObject* call(R (*f)(%(A%n%:, %)), PyObject* args, PyObject* keywords) +inline PyObject* call(R (*f)(%(A%n%:, %)), PyObject* args, PyObject* keywords) { return detail::returning::call(f, args, keywords); } @@ -49,7 +49,7 @@ PyObject* call(R (*f)(%(A%n%:, %)), PyObject* args, PyObject* keywords) , map(lambda cv: gen_functions( '''template -PyObject* call(R (A0::*f)(%(A%+%:, %))%1, PyObject* args, PyObject* keywords) +inline PyObject* call(R (A0::*f)(%(A%+%:, %))%1, PyObject* args, PyObject* keywords) { return detail::returning::call(f, args, keywords); } diff --git a/test/m1.cpp b/test/m1.cpp index db450f77..78471bfc 100644 --- a/test/m1.cpp +++ b/test/m1.cpp @@ -4,15 +4,13 @@ // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. -// Seems to be neccessary to suppress an ICE with MSVC -#include - #include "simple_type.hpp" #include "complicated.hpp" #include #include #include #include +#include #include #include #include @@ -53,17 +51,10 @@ PyTypeObject NoddyType = { }; // Create a Noddy containing 42 -extern "C" PyObject* -new_noddy(PyObject* self, PyObject* args) +PyObject* new_noddy() { - NoddyObject* noddy; - - if (!PyArg_ParseTuple(args,":new_noddy")) - return NULL; - - noddy = PyObject_New(NoddyObject, &NoddyType); + NoddyObject* noddy = PyObject_New(NoddyObject, &NoddyType); noddy->x = 42; - return (PyObject*)noddy; } @@ -92,27 +83,13 @@ PyTypeObject SimpleType = { }; // Create a Simple containing "hello, world" -extern "C" PyObject* -new_simple(PyObject* self, PyObject* args) +PyObject* new_simple() { - SimpleObject* simple; - - if (!PyArg_ParseTuple(args,":new_simple")) - return NULL; - - simple = PyObject_New(SimpleObject, &SimpleType); + SimpleObject* simple = PyObject_New(SimpleObject, &SimpleType); simple->x.s = "hello, world"; - return (PyObject*)simple; } -// Initial method table for the module -static PyMethodDef methods[] = { - { "new_noddy", new_noddy, METH_VARARGS }, - { "new_simple", new_simple, METH_VARARGS }, - {0, 0, 0, 0} -}; - // // Declare some wrappers/unwrappers to test the low-level conversion // mechanism. See boost/python/converter/source.hpp,target.hpp for a @@ -252,7 +229,7 @@ simple const& g(simple const& x) BOOST_PYTHON_MODULE_INIT(m1) { - PyObject* m1 = Py_InitModule(const_cast("m1"), methods); + boost::python::module m1("m1"); // Create the converters; they are self-registering/unregistering. static int_wrapper wrap_int; @@ -262,63 +239,45 @@ BOOST_PYTHON_MODULE_INIT(m1) static noddy_int_ref_unwrapper unwrap_int3; static simple_ref_unwrapper unwrap_simple; static simple_const_ref_unwrapper unwrap_simple_const_ref; -#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - // These compilers will need additional converters static simple_ref_wrapper wrap_simple_ref; -#endif // This unwrapper extracts pointers and references to the "complicated" class. static boost::python::converter::class_unwrapper unwrap_complicated; - PyObject* d = PyModule_GetDict(m1); - if (d == NULL) - return; - // Insert the extension metaclass object - if (PyDict_SetItemString( - d, "xclass", (PyObject *)boost::python::object::class_metatype()) < 0) - return; - + m1.add(boost::python::objects::class_metatype(), "xclass"); + // Insert the base class for all extension classes - if (PyDict_SetItemString( - d, "xinst", (PyObject *)boost::python::object::class_type()) < 0) - return; + m1.add(boost::python::objects::class_type(), "xinst"); + m1.def(new_noddy, "new_noddy"); + m1.def(new_simple, "new_simple"); + // Expose f() - if (PyDict_SetItemString( - d, "f", boost::python::make_function(f)) < 0) - return; + m1.def(f, "f"); // Expose g() - if (PyDict_SetItemString( - d, "g", boost::python::make_function(g)) < 0) - return; + m1.def(g, "g"); // Expose complicated's get_n() member function. See newtest.py // for how it's used to build an extension class. - if (PyDict_SetItemString( - d, "get_n", boost::python::make_function(&complicated::get_n)) < 0) - return; + m1.def(&complicated::get_n, "get_n"); // Expose complicated::complicated(simple const&, int) as init1 - if (PyDict_SetItemString( - d, "init1" - , boost::python::make_constructor< - complicated - , boost::mpl::type_list - , boost::python::object::value_holder_generator>() - ) < 0) - return; - - // Expose complicated::complicated(simple const&) as init2 - if (PyDict_SetItemString( - d, "init2" - , boost::python::make_constructor< - complicated - , boost::mpl::type_list - , boost::python::object::value_holder_generator>() - ) < 0) - return; + boost::python::objects::function* init = boost::python::make_constructor< + complicated + , boost::mpl::type_list + , boost::python::objects::value_holder_generator>(); + + boost::python::ref manager(init); + + init->add_overload( + boost::python::make_constructor< + complicated + , boost::mpl::type_list + , boost::python::objects::value_holder_generator>()); + + m1.add(manager, "init1"); } #include "module_tail.cpp" diff --git a/test/m2.cpp b/test/m2.cpp index 377ce02e..3c5267d0 100644 --- a/test/m2.cpp +++ b/test/m2.cpp @@ -7,10 +7,6 @@ // This module exercises the converters exposed in m1 at a low level // by exposing raw Python extension functions that use wrap<> and // unwrap<> objects. - -// Seems to be neccessary to suppress an ICE with MSVC -#include - #include #include #include "simple_type.hpp" @@ -22,106 +18,40 @@ extern "C" { // Get a simple (by value) from the argument, and return the // string it holds. - PyObject* - unwrap_simple(PyObject* self, PyObject* args) + PyObject* unwrap_simple(simple x) { - PyObject* p; - if (!PyArg_ParseTuple(args, "O", &p)) - return 0; - - boost::python::unwrap in(p); - if (!in) - return 0; - - simple x = *in; - return PyString_FromString(x.s); } // Likewise, but demands that its possible to get a non-const // reference to the simple. - PyObject* - unwrap_simple_ref(PyObject* self, PyObject* args) + PyObject* unwrap_simple_ref(simple& x) { - PyObject* p; - if (!PyArg_ParseTuple(args, "O", &p)) - return 0; - - unwrap in(p); - if (!in) - return 0; - - simple& x = *in; - return PyString_FromString(x.s); } // Likewise, with a const reference to the simple object. - PyObject* - unwrap_simple_const_ref(PyObject* self, PyObject* args) + PyObject* unwrap_simple_const_ref(simple const& x) { - PyObject* p; - if (!PyArg_ParseTuple(args, "O", &p)) - return 0; - - unwrap in(p); - if (!in) - return 0; - - simple const& x = *in; - return PyString_FromString(x.s); } // Get an int (by value) from the argument, and convert it to a // Python Int. - PyObject* - unwrap_int(PyObject* self, PyObject* args) + PyObject* unwrap_int(int x) { - PyObject* p; - if (!PyArg_ParseTuple(args, "O", &p)) - return 0; - - unwrap in(p); - if (!in) - return 0; - - int x = *in; - return PyInt_FromLong(x); } // Get a non-const reference to an int from the argument - PyObject* - unwrap_int_ref(PyObject* self, PyObject* args) + PyObject* unwrap_int_ref(int& x) { - PyObject* p; - if (!PyArg_ParseTuple(args, "O", &p)) - return 0; - - unwrap in(p); - if (!in) - return 0; - - int& x = *in; - return PyInt_FromLong(x); } // Get a const reference to an int from the argument. - PyObject* - unwrap_int_const_ref(PyObject* self, PyObject* args) + PyObject* unwrap_int_const_ref(int const& x) { - PyObject* p; - if (!PyArg_ParseTuple(args, "O", &p)) - return 0; - - unwrap in(p); - if (!in) - return 0; - - int const& x = *in; - return PyInt_FromLong(x); } @@ -134,89 +64,28 @@ template struct xxxx; // rewrap extracts a T from the argument, then converts the T back // to a PyObject* and returns it. template -PyObject* -rewrap(PyObject* self, PyObject* args, xxxx* = 0) +struct rewrap { - PyObject* p; - if (!PyArg_ParseTuple(args, "O", &p)) - return 0; - - boost::python::unwrap in(p); - if (!in) - return 0; - - boost::python::wrap out; - if (!out) - return 0; - - T x = *in; - return out(x); -} - -extern "C" -{ - // - // Use rewrap to test simple, simple&, simple const&, int, - // int&, int const& - // - PyObject* - wrap_simple(PyObject* self, PyObject* args) - { - return rewrap(self, args); - } - - PyObject* - wrap_simple_ref(PyObject* self, PyObject* args) - { - return rewrap(self, args); - } - - PyObject* - wrap_simple_const_ref(PyObject* self, PyObject* args) - { - return rewrap(self, args); - } - - PyObject* - wrap_int(PyObject* self, PyObject* args) - { - return rewrap(self, args); - } - - PyObject* - wrap_int_ref(PyObject* self, PyObject* args) - { - return rewrap(self, args); - } - - PyObject* - wrap_int_const_ref(PyObject* self, PyObject* args) - { - return rewrap(self, args); - } -} - -PyMethodDef initial_methods[] = -{ - { "unwrap_int", unwrap_int, METH_VARARGS, 0 }, - { "unwrap_int_ref", unwrap_int_ref, METH_VARARGS, 0 }, - { "unwrap_int_const_ref", unwrap_int_const_ref, METH_VARARGS, 0 }, - { "unwrap_simple", unwrap_simple, METH_VARARGS, 0 }, - { "unwrap_simple_ref", unwrap_simple_ref, METH_VARARGS, 0 }, - { "unwrap_simple_const_ref", unwrap_simple_const_ref, METH_VARARGS, 0 }, - - { "wrap_int", wrap_int, METH_VARARGS, 0 }, - { "wrap_int_ref", wrap_int_ref, METH_VARARGS, 0 }, - { "wrap_int_const_ref", wrap_int_const_ref, METH_VARARGS, 0 }, - { "wrap_simple", wrap_simple, METH_VARARGS, 0 }, - { "wrap_simple_ref", wrap_simple_ref, METH_VARARGS, 0 }, - { "wrap_simple_const_ref", wrap_simple_const_ref, METH_VARARGS, 0 }, - { 0, 0, 0, 0 } + static T f(T x) { return x; } }; BOOST_PYTHON_MODULE_INIT(m2) { - Py_InitModule(const_cast("m2"), initial_methods); + boost::python::module m2("m2"); + + m2.def(unwrap_int, "unwrap_int"); + m2.def(unwrap_int_ref, "unwrap_int_ref"); + m2.def(unwrap_int_const_ref, "unwrap_int_const_ref"); + m2.def(unwrap_simple, "unwrap_simple"); + m2.def(unwrap_simple_ref, "unwrap_simple_ref"); + m2.def(unwrap_simple_const_ref, "unwrap_simple_const_ref"); + + m2.def(&rewrap::f, "wrap_int"); + m2.def(&rewrap::f, "wrap_int_ref"); + m2.def(&rewrap::f, "wrap_int_const_ref"); + m2.def(&rewrap::f, "wrap_simple"); + m2.def(&rewrap::f, "wrap_simple_ref"); + m2.def(&rewrap::f, "wrap_simple_const_ref"); } #include "module_tail.cpp" diff --git a/test/newtest.py b/test/newtest.py index b866258c..d29ac129 100644 --- a/test/newtest.py +++ b/test/newtest.py @@ -20,16 +20,14 @@ >>> unwrap_int(5) 5 -Can't get a reference to a built-in integer object +Can't get a non-const reference to a built-in integer object >>> try: ... unwrap_int_ref(7) ... except: pass ... else: print 'no exception' ->>> try: -... unwrap_int_const_ref(9) -... except: pass -... else: print 'no exception' +>>> unwrap_int_const_ref(9) +9 >>> wrap_int(n) 42 @@ -63,16 +61,11 @@ Create an extension class which wraps "complicated" (init1 and get_n) are a complicated constructor and member function, respectively. >>> C = xclass('C', (xinst,), {'__init__': init1, 'get_n': get_n}) ->>> c = C(s, 99) ->>> c.get_n() +>>> c1 = C(s, 99) +>>> c1.get_n() 99 - -Create another extension class which wraps "complicated" (init2 is a -different constructor -- no overloading yet). - ->>> D = xclass('D', (xinst,), {'__init__': init2, 'get_n': get_n}) ->>> d = D(s) ->>> d.get_n() +>>> c2 = C(s) +>>> c2.get_n() 0 """