Pyste patch: fix 3 bugs and add new-style polymorphism
The attached patch fixes the following bugs in pyste: - boost::non_copyable was not always inserted at the end of the class_ template declaration (resolved by changing the call order of the Export* methods) - policy for overloaded member functions was passed as another parameters to def() instead of using [policy]. Fix in ExportMethods. - default parameters overload resolution failed on virtual when using an instance of the base C++ object (see VirtualNonCopyableTest for detail). New-polymorphism is now used for virtual member function wrapper (it was the easiest way to get everything working for the last bug). It should be noted that default parameter for *protected* virtual member functions has been disabled (no simple robust solution at the current time). The attached file main.cpp/TestOverload.cpp is an output of the new code generated by pyste for the attached test cases. TestOverLoad.pyste/h and overloadtest.py demonstrates the bugs. The code generated by this patches has been successfully compiled on VC++ 2003 with boost 1.32. The generator has been tested on pyogre (100 classes, 3800 methods/variables) with success. Baptiste.
Hi Baptiste, Baptiste Lepilleur wrote:
The attached patch fixes the following bugs in pyste:
<snip patch description>
Thanks a lot for the patch! Sorry for taking so long to respond, I moved recently and was without an internet connection until now. I applied your patch, but I'm having trouble compiling the generated file with the latest Boost-CVS. I'm using MSVC 6.0 on Windows XP. The command line used was: cl /nologo /Zm200 /LD /YX /GR /GX -I. -Id:/programming/libraries/boost-cvs/boost -Id:/bin/python/include new.cpp /link /libpath:d:/bin/python/libs /libpath:d:/programming/libraries/boost-cvs/lib /dll boost_python.lib The source file is attached. Does anyone have an idea of what the problem is? Best Regards, Bruno. // Boost Includes ============================================================== #include <boost/python.hpp> #include <boost/cstdint.hpp> // Includes ==================================================================== #include <TestOverload.h> // Using ======================================================================= using namespace boost::python; // Declarations ================================================================ namespace { BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(NonVirtual_set_overloads_1_3, set, 1, 3) struct VirtualNonCopyable_Wrapper: VirtualNonCopyable, wrapper< VirtualNonCopyable > { VirtualNonCopyable_Wrapper(): VirtualNonCopyable() {} void set(const std::string& p0, int p1, int p2) { if (override f = this->get_override("set")) call< void >( f.ptr(), p0, p1, p2); VirtualNonCopyable::set(p0, p1, p2); } static void default_set_1(VirtualNonCopyable &self, const std::string& p0) { self.set(p0); } static void default_set_2(VirtualNonCopyable &self, const std::string& p0, int p1) { self.set(p0, p1); } void default_set(const std::string& p0, int p1, int p2) { VirtualNonCopyable::set(p0, p1, p2); } }; BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(NonVirtualReturnValuePolicy_set_overloads_1_3, set, 1, 3) struct VirtualReturnValuePolicy_Wrapper: VirtualReturnValuePolicy, wrapper< VirtualReturnValuePolicy > { VirtualReturnValuePolicy_Wrapper(): VirtualReturnValuePolicy() {} ValueHolder* set(const std::string& p0, int p1, int p2) { if (override f = this->get_override("set")) return call< ValueHolder* >( f.ptr(), p0, p1, p2); return VirtualReturnValuePolicy::set(p0, p1, p2); } static ValueHolder* default_set_1(VirtualReturnValuePolicy &self, const std::string& p0) { return self.set(p0); } static ValueHolder* default_set_2(VirtualReturnValuePolicy &self, const std::string& p0, int p1) { return self.set(p0, p1); } ValueHolder* default_set(const std::string& p0, int p1, int p2) { return VirtualReturnValuePolicy::set(p0, p1, p2); } ValueHolder* set(int p0, int p1) { if (override f = this->get_override("set")) return call< ValueHolder* >( f.ptr(), p0, p1); return VirtualReturnValuePolicy::set(p0, p1); } static ValueHolder* default_set_0(VirtualReturnValuePolicy &self) { return self.set(); } static ValueHolder* default_set_1(VirtualReturnValuePolicy &self, int p0) { return self.set(p0); } ValueHolder* default_set(int p0, int p1) { return VirtualReturnValuePolicy::set(p0, p1); } }; }// namespace // Module ====================================================================== BOOST_PYTHON_MODULE(new_) { class_< NonVirtual, boost::noncopyable >("NonVirtual", no_init) .def_readwrite("name", &NonVirtual::name) .def_readwrite("size", &NonVirtual::size) .def_readwrite("width", &NonVirtual::width) .def("set", &NonVirtual::set, NonVirtual_set_overloads_1_3()) ; class_< VirtualNonCopyable_Wrapper, boost::noncopyable >("VirtualNonCopyable", init< >()) .def("set", VirtualNonCopyable_Wrapper::default_set_1) .def("set", VirtualNonCopyable_Wrapper::default_set_2) .def("set", &VirtualNonCopyable::set, &VirtualNonCopyable_Wrapper::default_set) .def_readwrite("name", &VirtualNonCopyable::name) .def_readwrite("size", &VirtualNonCopyable::size) .def_readwrite("width", &VirtualNonCopyable::width) ; class_< ValueHolder, boost::noncopyable >("ValueHolder", init< >()) .def_readwrite("name", &ValueHolder::name) ; def("getVirtualNonCopyable", &getVirtualNonCopyable, return_value_policy< reference_existing_object >()); class_< NonVirtualReturnValuePolicy, boost::noncopyable >("NonVirtualReturnValuePolicy", init< >()) .def_readwrite("name", &NonVirtualReturnValuePolicy::name) .def_readwrite("size", &NonVirtualReturnValuePolicy::size) .def_readwrite("width", &NonVirtualReturnValuePolicy::width) .def("set", &NonVirtualReturnValuePolicy::set, NonVirtualReturnValuePolicy_set_overloads_1_3()[ return_internal_reference< 1 >() ]) ; class_< VirtualReturnValuePolicy_Wrapper, boost::noncopyable >("VirtualReturnValuePolicy", init< >()) .def("set", (ValueHolder* (*)( VirtualReturnValuePolicy &, const std::string&))VirtualReturnValuePolicy_Wrapper::default_set_1, return_internal_reference< 1 >()) .def("set", (ValueHolder* (*)( VirtualReturnValuePolicy &, const std::string&, int))VirtualReturnValuePolicy_Wrapper::default_set_2, return_internal_reference< 1 >()) .def("set", (ValueHolder* (VirtualReturnValuePolicy::*)(const std::string&, int, int) )&VirtualReturnValuePolicy::set, (ValueHolder* (VirtualReturnValuePolicy_Wrapper::*)(const std::string&, int, int))&VirtualReturnValuePolicy_Wrapper::default_set, return_internal_reference< 1 >()) .def("set", (ValueHolder* (*)( VirtualReturnValuePolicy &))VirtualReturnValuePolicy_Wrapper::default_set_0, return_internal_reference< 1 >()) .def("set", (ValueHolder* (*)( VirtualReturnValuePolicy &, int))VirtualReturnValuePolicy_Wrapper::default_set_1, return_internal_reference< 1 >()) .def("set", (ValueHolder* (VirtualReturnValuePolicy::*)(int, int) )&VirtualReturnValuePolicy::set, (ValueHolder* (VirtualReturnValuePolicy_Wrapper::*)(int, int))&VirtualReturnValuePolicy_Wrapper::default_set, return_internal_reference< 1 >()) .def_readwrite("name", &VirtualReturnValuePolicy::name) .def_readwrite("size", &VirtualReturnValuePolicy::size) .def_readwrite("width", &VirtualReturnValuePolicy::width) ; def("getVirtualReturnValuePolicy", &getVirtualReturnValuePolicy, return_value_policy< reference_existing_object >()); }
I never tried building on VC++ 6 (I'm already struggling with VC++ 7.1 limits). I attached the build log with the errors. Basically many errors like: E:\prg\vc\Lib\boost_1_32_0\boost/python/class.hpp(404) : error C2657: '`global namespace'::*' found at the start of a statement (did you forget to specify a type?) E:\prg\vc\Lib\boost_1_32_0\boost/python/class.hpp(381) : see reference to function template instantiation 'class boost::python::api::object __thiscall boost::python::?$class_@UVirtualNonCopyable_Wrapper@?%new.cpp253401447@@Vnon copyable@noncopyable_@boost@@Unot_specified@detail@python@5@U6785@::make_fn_ impl(int *,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > VirtualNonCopyable::*,struct boost::mpl::bool_<0>,char *,struct boost::mpl::bool_<1>)' being compiled template <class T, class D, class B> object make_fn_impl(T*, D B::*pm_, mpl::false_, char*, mpl::true_) { D T::*pm = pm_; /// <=== line 404 of class.hpp return python::make_getter(pm); } It doesn't make sense for me. A compiler bug ? Baptiste. ----- Original Message ----- From: "Nicodemus" <nicodemus@esss.com.br> To: <c++-sig@python.org> Cc: "Baptiste Lepilleur" <gaiacrtn@free.fr> Sent: Monday, January 03, 2005 8:23 PM Subject: [C++-sig] Re: Pyste patch: fix 3 bugs and add new-style polymorphism
Hi Baptiste,
Baptiste Lepilleur wrote:
The attached patch fixes the following bugs in pyste:
<snip patch description>
Thanks a lot for the patch! Sorry for taking so long to respond, I moved recently and was without an internet connection until now.
I applied your patch, but I'm having trouble compiling the generated file with the latest Boost-CVS. I'm using MSVC 6.0 on Windows XP. The command line used was:
cl /nologo /Zm200 /LD /YX /GR /GX -I. -Id:/programming/libraries/boost-cvs/boost -Id:/bin/python/include new.cpp /link /libpath:d:/bin/python/libs /libpath:d:/programming/libraries/boost-cvs/lib /dll boost_python.lib
The source file is attached. Does anyone have an idea of what the problem is?
Best Regards, Bruno.
---------------------------------------------------------------------------- ----
// Boost Includes
#include <boost/python.hpp> #include <boost/cstdint.hpp>
// Includes ==================================================================== #include <TestOverload.h>
// Using ======================================================================= using namespace boost::python;
// Declarations ================================================================ namespace {
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(NonVirtual_set_overloads_1_3, set, 1, 3)
struct VirtualNonCopyable_Wrapper: VirtualNonCopyable, wrapper< VirtualNonCopyable > { VirtualNonCopyable_Wrapper(): VirtualNonCopyable() {}
void set(const std::string& p0, int p1, int p2) { if (override f = this->get_override("set")) call< void >( f.ptr(), p0, p1, p2); VirtualNonCopyable::set(p0, p1, p2); }
static void default_set_1(VirtualNonCopyable &self, const std::string&
============================================================== p0) {
self.set(p0); }
static void default_set_2(VirtualNonCopyable &self, const std::string&
p0, int p1) {
self.set(p0, p1); }
void default_set(const std::string& p0, int p1, int p2) { VirtualNonCopyable::set(p0, p1, p2); }
};
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(NonVirtualReturnValuePolicy_set_overl oads_1_3, set, 1, 3)
struct VirtualReturnValuePolicy_Wrapper: VirtualReturnValuePolicy,
{ VirtualReturnValuePolicy_Wrapper(): VirtualReturnValuePolicy() {}
ValueHolder* set(const std::string& p0, int p1, int p2) { if (override f = this->get_override("set")) return call< ValueHolder* >( f.ptr(), p0, p1, p2); return VirtualReturnValuePolicy::set(p0, p1, p2); }
static ValueHolder* default_set_1(VirtualReturnValuePolicy &self, const std::string& p0) { return self.set(p0); }
static ValueHolder* default_set_2(VirtualReturnValuePolicy &self, const std::string& p0, int p1) { return self.set(p0, p1); }
ValueHolder* default_set(const std::string& p0, int p1, int p2) { return VirtualReturnValuePolicy::set(p0, p1, p2); }
ValueHolder* set(int p0, int p1) { if (override f = this->get_override("set")) return call< ValueHolder* >( f.ptr(), p0, p1); return VirtualReturnValuePolicy::set(p0, p1); }
static ValueHolder* default_set_0(VirtualReturnValuePolicy &self) { return self.set(); }
static ValueHolder* default_set_1(VirtualReturnValuePolicy &self, int
wrapper< VirtualReturnValuePolicy > p0) {
return self.set(p0); }
ValueHolder* default_set(int p0, int p1) { return VirtualReturnValuePolicy::set(p0, p1); }
};
}// namespace
// Module
======================================================================
BOOST_PYTHON_MODULE(new_) { class_< NonVirtual, boost::noncopyable >("NonVirtual", no_init) .def_readwrite("name", &NonVirtual::name) .def_readwrite("size", &NonVirtual::size) .def_readwrite("width", &NonVirtual::width) .def("set", &NonVirtual::set, NonVirtual_set_overloads_1_3()) ;
class_< VirtualNonCopyable_Wrapper, boost::noncopyable ("VirtualNonCopyable", init< >()) .def("set", VirtualNonCopyable_Wrapper::default_set_1) .def("set", VirtualNonCopyable_Wrapper::default_set_2) .def("set", &VirtualNonCopyable::set, &VirtualNonCopyable_Wrapper::default_set) .def_readwrite("name", &VirtualNonCopyable::name) .def_readwrite("size", &VirtualNonCopyable::size) .def_readwrite("width", &VirtualNonCopyable::width) ;
class_< ValueHolder, boost::noncopyable >("ValueHolder", init< >()) .def_readwrite("name", &ValueHolder::name) ;
def("getVirtualNonCopyable", &getVirtualNonCopyable, return_value_policy< reference_existing_object >()); class_< NonVirtualReturnValuePolicy, boost::noncopyable ("NonVirtualReturnValuePolicy", init< >()) .def_readwrite("name", &NonVirtualReturnValuePolicy::name) .def_readwrite("size", &NonVirtualReturnValuePolicy::size) .def_readwrite("width", &NonVirtualReturnValuePolicy::width) .def("set", &NonVirtualReturnValuePolicy::set, NonVirtualReturnValuePolicy_set_overloads_1_3()[ return_internal_reference< 1 >() ]) ;
class_< VirtualReturnValuePolicy_Wrapper, boost::noncopyable ("VirtualReturnValuePolicy", init< >()) .def("set", (ValueHolder* (*)( VirtualReturnValuePolicy &, const std::string&))VirtualReturnValuePolicy_Wrapper::default_set_1, return_internal_reference< 1 >()) .def("set", (ValueHolder* (*)( VirtualReturnValuePolicy &, const std::string&, int))VirtualReturnValuePolicy_Wrapper::default_set_2, return_internal_reference< 1 >()) .def("set", (ValueHolder* (VirtualReturnValuePolicy::*)(const std::string&, int, int) )&VirtualReturnValuePolicy::set, (ValueHolder* (VirtualReturnValuePolicy_Wrapper::*)(const std::string&, int, int))&VirtualReturnValuePolicy_Wrapper::default_set, return_internal_reference< 1 >()) .def("set", (ValueHolder* (*)( VirtualReturnValuePolicy &))VirtualReturnValuePolicy_Wrapper::default_set_0, return_internal_reference< 1 >()) .def("set", (ValueHolder* (*)( VirtualReturnValuePolicy &, int))VirtualReturnValuePolicy_Wrapper::default_set_1, return_internal_reference< 1 >()) .def("set", (ValueHolder* (VirtualReturnValuePolicy::*)(int, int) )&VirtualReturnValuePolicy::set, (ValueHolder* (VirtualReturnValuePolicy_Wrapper::*)(int, int))&VirtualReturnValuePolicy_Wrapper::default_set, return_internal_reference< 1 >()) .def_readwrite("name", &VirtualReturnValuePolicy::name) .def_readwrite("size", &VirtualReturnValuePolicy::size) .def_readwrite("width", &VirtualReturnValuePolicy::width) ;
def("getVirtualReturnValuePolicy", &getVirtualReturnValuePolicy, return_value_policy< reference_existing_object >()); }
---------------------------------------------------------------------------- ----
_______________________________________________ C++-sig mailing list C++-sig@python.org http://mail.python.org/mailman/listinfo/c++-sig
participants (2)
-
Baptiste Lepilleur -
Nicodemus