Extracting arguments from kwargs in boost :: python

I have a C ++ class that I create in a python module using boost :: python. I have several functions that I want to use for keyword arguments. I installed wrapper functions to go to raw_arguments and this works fine, but I want to build some error checking for the function arguments. Is there a standard way to do this?

My function prototype in C ++ looks something like this:

double MyClass::myFunction(int a, int b, int c); 

The third argument is optional, with a default value of 0 (I implemented this in boost :: python, using macros so far). In python, I want to be able to achieve the following behavior:

 MyClass.my_function(1) # Raises exception MyClass.my_function(2, 3) # So that a = 2, b = 3 and c defaults to 0 MyClass.my_function(2, 3, 1) # As above, but now c = 1 MyClass.my_function(2, 3, 1, 3) # Raises exception MyClass.my_function(3, 1, c = 2) # So a = 3, b = 1 and c = 2 MyClass.my_function(a = 2, b = 2, c = 3) # Speaks for itself MyClass.my_function(b = 2, c = 1) # Raises exception 

Is there something in boost :: python or the raw_function shell that can make this easier, or do I need to write code to test it all myself? If I need it, how can I make exceptions? Is there a standard way to do this?

+6
source share
1 answer

The boost/python/args.hpp provides a family of classes for specifying keyword arguments. In particular, Boost.Python provides an arg type that represents a potential keyword argument. It overloads the comma operator to provide a more natural definition of the argument list.

Mapping myFunction in MyClass as my_function , where a , b and c are the keyword arguments, and c has a default value of 0 , which can be written as follows

 BOOST_PYTHON_MODULE(example) { namespace python = boost::python; python::class_<MyClass>("MyClass") .def("my_function", &MyClass::myFunction, (python::arg("a"), "b", python::arg("c")=0)) ; } 

Here is a complete example:

 #include <boost/python.hpp> class MyClass { public: double myFunction(int a, int b, int c) { return a + b + c; } }; BOOST_PYTHON_MODULE(example) { namespace python = boost::python; python::class_<MyClass>("MyClass") .def("my_function", &MyClass::myFunction, (python::arg("a"), "b", python::arg("c")=0)) ; } 

Interactive use:

 >>> import example >>> my_class = example.MyClass() >>> my_class.my_function(1) Traceback (most recent call last): File "<stdin>", line 1, in <module> Boost.Python.ArgumentError: Python argument types in MyClass.my_function(MyClass, int) did not match C++ signature: my_function(MyClass {lvalue}, int a, int b, int c=0) >>> assert(5 == my_class.my_function(2, 3)) >>> assert(6 == my_class.my_function(2, 3, 1)) >>> my_class.my_function(2, 3, 1, 3) Traceback (most recent call last): File "<stdin>", line 1, in <module> Boost.Python.ArgumentError: Python argument types in MyClass.my_function(MyClass, int, int, int, int) did not match C++ signature: my_function(MyClass {lvalue}, int a, int b, int c=0) >>> assert(6 == my_class.my_function(3, 1, c=2)) >>> assert(7 == my_class.my_function(a=2, b=2, c=3)) >>> my_class.my_function(b=2, c=1) Traceback (most recent call last): File "<stdin>", line 1, in <module> Boost.Python.ArgumentError: Python argument types in MyClass.my_function(MyClass) did not match C++ signature: my_function(MyClass {lvalue}, int a, int b, int c=0) 
+13
source

Source: https://habr.com/ru/post/945466/


All Articles