Opened 13 years ago

Last modified 13 years ago

#3710 new Bugs

error incorrect when calling boost::python function via functools.partial

Reported by: anonymous Owned by: troy d. straszheim
Milestone: Boost 1.42.0 Component: python USE GITHUB
Version: Boost 1.41.0 Severity: Problem
Keywords: Cc:

Description

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.

Change History (2)

comment:1 by anonymous, 13 years ago

Owner: changed from Dave Abrahams to troy d. straszheim

comment:2 by troy d. straszheim, 13 years ago

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)
Note: See TracTickets for help on using tickets.