So, this isn't just a bool-int issue, you can get the same thing with int and double:

std::string takes_bool(bool b) { return "bool"; } std::string takes_int(int b) { return "int"; } std::string takes_double(double b) { return "double"; }


BOOST_PYTHON_MODULE(overload_resolution) { def("bid", takes_bool); def("bid", takes_int);
  def("bid", takes_double);


def("bdi", takes_bool); def("bdi", takes_double); def("bdi", takes_int); }


In [11]: its_an_int = 3

In [12]: bid(its_an_int)
Out[12]: 'double'

In [13]: bdi(its_an_int)
Out[13]: 'int'

In [14]: bid(True)
Out[14]: 'double'

The current rule for overload resolution are simply 'first match in reverse order of registration'. You could relatively easily make this 'first match in forward order of registration'. The library currently has no notion of one function being a better match than another, for a given set of arguments. It looks like it would be interesting enough to implement, but it isn't clear what those rules would be or if the runtime cost would be worth it. For instance, this situation:

  void fn_di(double, int);
  void fn_id(int, double);

  def("f", fn_di);
  def("f", fn_id);

  >>> f(3,3)

In C++, of course, that's a compile-time error. In python, would you check all overloads for equally-good matches, and if so, throw some kind of ambiguous_function_call exception?

Maybe somebody else has more ideas on this. I think you could tighten up the automatic conversion rules (like the patch below does for int and bool), so that one would have to clarify at the call site which function you're calling:

  >> f(float(3), 3)

this seems the most practical to me at the moment. It would break a bunch of python code , but by adding casts, the old python code could be made to work with boost.python bindings pre- and post- this change.

-t

troy d. straszheim wrote:
I have a quasi-fix for this to the library itself, (see diff below) buuut it breaks a certain case: if you have a wrapped c++ function that takes a bool, and you try to pass it an int, you get a

    ArgumentError: Python argument types in
        builtin_converters_ext.rewrap_const_reference_bool(int)
    did not match C++ signature:
        rewrap_const_reference_bool(bool)

so you have to call the function with an explicit cast to bool:

c++:

  void takes_a_bool(bool b) { ... };

  def("py_takesbool", takes_a_bool);

py:

  py_takesbool(bool(33))

to get things to work.   This breaks a lot of tests, I'm digging further.


Index: converter/builtin_converters.cpp
===================================================================
--- converter/builtin_converters.cpp    (revision 51812)
+++ converter/builtin_converters.cpp    (working copy)
@@ -99,8 +99,13 @@
           if (number_methods == 0)
               return 0;

-          return (PyInt_Check(obj) || PyLong_Check(obj))
-              ? &number_methods->nb_int : 0;
+          return (
+#if PY_VERSION_HEX >= 0x02040000
+          !PyBool_Check(obj) &&
+#endif
+          (PyInt_Check(obj) || PyLong_Check(obj)))
+
+        ? &number_methods->nb_int : 0;
       }
       static PyTypeObject const* get_pytype() { return &PyInt_Type;}
   };
@@ -135,7 +140,11 @@
           if (number_methods == 0)
               return 0;

-          return (PyInt_Check(obj) || PyLong_Check(obj))
+          return (
+#if PY_VERSION_HEX >= 0x02040000
+          !PyBool_Check(obj) &&
+#endif
+          (PyInt_Check(obj) || PyLong_Check(obj)))
               ? &py_object_identity : 0;
       }
       static PyTypeObject const* get_pytype() { return &PyInt_Type;}
@@ -226,7 +235,11 @@
   {
       static unaryfunc* get_slot(PyObject* obj)
       {
+#if PY_VERSION_HEX >= 0x02040000
+    return obj == Py_None || PyBool_Check(obj) ? &py_object_identity : 0;
+#else
return obj == Py_None || PyInt_Check(obj) ? &py_object_identity : 0;
+#endif
       }

       static bool extract(PyObject* intermediate)
_______________________________________________
Cplusplus-sig mailing list
Cplusplus-sig@python.org
http://mail.python.org/mailman/listinfo/cplusplus-sig

_______________________________________________
Cplusplus-sig mailing list
Cplusplus-sig@python.org
http://mail.python.org/mailman/listinfo/cplusplus-sig

Reply via email to