functools.partial vs boost::python
Has anyone noticed that a function created with boost::python using args() to give keyword arguments doesn't seem to work with functools.partial keyword arguments (but does with positional args)? For example, I have this function: class_<boost_uniform_real_wrap> ("uniform_real", "Uniform float distribution", bp::init<rng_t&,double,double>( (bp::arg ("rng"), bp::arg ("min"), bp::arg ("max"))... Then: from functools import partial f = partial (uniform_real, rng=rng1) << using keyword doesn't work f (1,2) ArgumentError: Python argument types in uniform_real.__init__(uniform_real, int, int) did not match C++ signature: __init__(_object*, boost::random::mersenne_twister<unsigned int, 32, 624, 397, 31, 2567483615u, 11, 7, 2636928640u, 15, 4022730752u, 18, 3346425566u> {lvalue} rng, double min, double max) But this works: from functools import partial f = partial (uniform_real, rng1) << pos arg does work In [27]: f(1,2) Out[27]: uniform_real(1,2)
Neal Becker wrote:
Has anyone noticed that a function created with boost::python using args() to give keyword arguments doesn't seem to work with functools.partial keyword arguments (but does with positional args)?
For example, I have this function: class_<boost_uniform_real_wrap> ("uniform_real", "Uniform float distribution", bp::init<rng_t&,double,double>( (bp::arg ("rng"), bp::arg ("min"), bp::arg ("max"))...
Then: from functools import partial f = partial (uniform_real, rng=rng1) << using keyword doesn't work f (1,2) ArgumentError: Python argument types in uniform_real.__init__(uniform_real, int, int) did not match C++ signature: __init__(_object*, boost::random::mersenne_twister<unsigned int, 32, 624, 397, 31, 2567483615u, 11, 7, 2636928640u, 15, 4022730752u, 18, 3346425566u> {lvalue} rng, double min, double max)
But this works: from functools import partial f = partial (uniform_real, rng1) << pos arg does work
In [27]: f(1,2) Out[27]: uniform_real(1,2)
That doesn't work for pure python functions either:
def f(x,y,z): return x*100 + y*10 + z ... from functools import partial as p p(f,x=1)(2,3) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: f() got multiple values for keyword argument 'x' p(f,x=1)(y=2,z=3) 123 p(f,1)(2,3) 123
The error message is misleading for sure. Boost.python is going through a list of overloads and trying them in order; if it runs out of overloads, it says nothing matched. I think I can get it to be smarter about this, lemme see... -t
troy d. straszheim wrote:
That doesn't work for pure python functions either:
def f(x,y,z): return x*100 + y*10 + z ... from functools import partial as p p(f,x=1)(2,3) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: f() got multiple values for keyword argument 'x' p(f,x=1)(y=2,z=3) 123 p(f,1)(2,3) 123
The error message is misleading for sure. Boost.python is going through a list of overloads and trying them in order; if it runs out of overloads, it says nothing matched. I think I can get it to be smarter about this, lemme see...
Trac ticket here: https://svn.boost.org/trac/boost/ticket/3710 For the record, here's a variation on the same theme. It doesn't have anything to do with functools, it is another symptom of our first-match overload resolution algorithm: int addem(int x, int y, int z) { return x*100 + y*10 + z; } BOOST_PYTHON_MODULE(functools_playnice_ext) { def("addem", &addem, (arg("x"), arg("y"), arg("z"))); }
from functools_playnice_ext import addem addem(1, 8, 2, x=4) Traceback (most recent call last): ... ArgumentError: Python argument types in functools_playnice_ext.addem(int, int, int) did not match C++ signature: addem(int x, int y, int z)
I've been thinking about this off and on for a while, to fix it right isn't trivial. I could put in a few checks for cases where a function is not overloaded, but that feels like hackery. -t
troy d. straszheim wrote: ...
I've been thinking about this off and on for a while, to fix it right isn't trivial. I could put in a few checks for cases where a function is not overloaded, but that feels like hackery.
No ideas, but I appreciate you're looking into this.
participants (2)
-
Neal Becker -
troy d. straszheim