[C++-sig] Getting Boost.Python to explain itself better?
I'm trying to debug an assertion error from Boost.Python, but having no luck. I'm not a C++ programmer, but to my eyes, it seems like my call should work. I'm using Boost 1.47.0 on an openSuSE 12.2 platform, with GCC/G++ 4.4. These parameters are fixed (that is, suggestions that I update any of them aren't going to fly - I am tied to those versions by factors outside my control). Here's a simple example, which used to work: >>> service.Provider >>> pro = service.Provider("Skip-hacking") >>> pro2 = service.Provider("Skip-hacking", {}) >>> pro3 = service.Provider("Skip-hacking", {}, 4001) I'm upgrading to accommodate some internal version dependency changes in other internal libraries, which should (in theory) have no effect on the build and functioning of the Boost.Python wrappers, certainly of this particular wrapper. Still, something's amiss. Here's the same example using my new version: >>> service.Provider >>> pro = service.Provider("Skip-hacking") >>> pro2 = service.Provider("Skip-hacking", {}) ArgumentError Python argument types in Provider.__init__(Provider, str, dict) did not match C++ signature: __init__(boost::python::api::object, std::string, std::map, std::allocator > >, int) __init__(boost::python::api::object, std::string, std::map, std::allocator > >) __init__(boost::python::api::object, std::string) [||1] >>> pro3 = service.Provider("Skip-hacking", {}, 4001) ArgumentError Python argument types in Provider.__init__(Provider, str, dict, int) did not match C++ signature: __init__(boost::python::api::object, std::string, std::map, std::allocator > >, int) __init__(boost::python::api::object, std::string, std::map, std::allocator > >) __init__(boost::python::api::object, std::string) [||1] It seems that Boost.Python doesn't think my empty dictionary is compatible with the std::map<...> type. Even if I pass a small, populated dictionary, it barfs: >>> pro4 = service.Provider("Skip-hacking", {"name": "skip"}) ArgumentError Python argument types in Provider.__init__(Provider, str, dict) did not match C++ signature: __init__(boost::python::api::object, std::string, std::map, std::allocator > >, int) __init__(boost::python::api::object, std::string, std::map, std::allocator > >) __init__(boost::python::api::object, std::string) [||1] The upgrade was only for version dependencies (we live in version dependency hell at work). There were no code changes to either the Boost.Python wrapper or the underlying C++ libraries between versions 9.4 and 9.5. In fact, this is very basic stuff in our environment which hasn't changed functionally in several years. I'd appreciate some insight about Boost.Python's thought processes. Why doesn't it like my dictionaries (empty or populated)? Thanks, Skip ___ Cplusplus-sig mailing list Cplusplus-sig@python.org https://mail.python.org/mailman/listinfo/cplusplus-sig
Re: [C++-sig] Getting Boost.Python to explain itself better?
On Fri, Jun 17, 2016 at 8:37 AM, Skip Montanaro wrote: > > >>> pro2 = service.Provider("Skip-hacking", {}) > ArgumentError Python argument types in > Provider.__init__(Provider, str, dict) > did not match C++ signature: > __init__(boost::python::api::object, std::string, > std::map, > std::allocator > >, > int) > __init__(boost::python::api::object, std::string, > std::map, > std::allocator > >) > __init__(boost::python::api::object, std::string) > [||1] After a bit more digging I think I found the problem, but am unclear how to solve it. Down a couple levels of dependencies there is a resource library in which a variant class is defined. It can contain int, string or bool objects, and uses a discriminator to decide which field is active. Kind of a union but without overlapping fields. (I make no comment on this class. It is what it is. I just have to live with it.) Structurally, it looks like this: class variant { public: ... enum Which { NONE = 0x00, INT = 0x01, STR = 0x02, BOOL = 0x03 }; ... private: Which which_; int i_; std::string s_; bool b_; } Somewhere along the way, someone needed to use one of these variants in a context where two variants needed to be compared, so a public operator< method was added. The data layout of the class instances didn't change. My programs were happily communicating with a server running the newer version of the class while it still relied on the older version. The addition of that public operator< method is what seems to have tripped up Boost.Python. Is there some way to convince it to accept the version of the variant class which contains this method? Thx, Skip ___ Cplusplus-sig mailing list Cplusplus-sig@python.org https://mail.python.org/mailman/listinfo/cplusplus-sig
Re: [C++-sig] Getting Boost.Python to explain itself better?
Hi Skip, On 17.06.2016 09:37, Skip Montanaro wrote: > I'm trying to debug an assertion error from Boost.Python, but having > no luck. I'm not a C++ programmer, but to my eyes, it seems like my > call should work. I'm using Boost 1.47.0 on an openSuSE 12.2 platform, > with GCC/G++ 4.4. These parameters are fixed (that is, suggestions > that I update any of them aren't going to fly - I am tied to those > versions by factors outside my control). Here's a simple example, > which used to work: you haven't shown any code, so I can only guess, but from the error messages I'd suspect you assume Boost.Python to automatically map between the Python dict type and your library's std::map. There is no automatic mapping of std::map<...>. The closest is the "map_indexing_suite" (http://boostorg.github.io/python/doc/html/reference/topics/indexing_support.html#topics.indexing_support.class_map_indexing_suite), but even with that you do need to explicitly specify the types to map. HTH, Stefan -- ...ich hab' noch einen Koffer in Berlin... ___ Cplusplus-sig mailing list Cplusplus-sig@python.org https://mail.python.org/mailman/listinfo/cplusplus-sig