Thread: [pygccxml-development] Py++ generates wrappers for final classes
Brought to you by:
mbaas,
roman_yakovenko
From: Julian S. <jul...@rs...> - 2007-07-09 04:58:19
|
Hello, I've run into a problem with Py++ (both with 0.9.0 and with trunk) when trying to expose a class like this: class Foo { public: virtual void bar() {} private: Foo() {} }; Py++ will generate a wrapper for Foo (since it contains a virtual function) when it shouldn't. Firstly, the generated code will not compile because the wrapper is derived from Foo and Foo cannot be used as a base class (Foo is final because it has no public or protected constructors.) And it doesn't make sense to generate a wrapper for Foo in the first place because Foo is final, and so function bar() cannot be overridden anyway. In the long term, I guess the proper fix is to not create wrappers for final classes. Is there a short-term workaround for this problem? I tried using finalize() from goodie_utils but that didn't work unfortunately. Thanks, Julian |
From: Roman Y. <rom...@gm...> - 2007-07-09 06:08:05
Attachments:
final_classes.cpp
|
On 7/9/07, Julian Scheid <jul...@rs...> wrote: > Hello, > > I've run into a problem with Py++ (both with 0.9.0 and with trunk) when > trying to expose a class like this: > > class Foo > { > public: > virtual void bar() {} > private: > Foo() {} > }; > > Py++ will generate a wrapper for Foo (since it contains a virtual > function) when it shouldn't. Firstly, the generated code will not > compile because the wrapper is derived from Foo and Foo cannot be used > as a base class (Foo is final because it has no public or protected > constructors.) What compiler do you use? I just checked this on MSVC 7.1 and it works fine. I attach the generated code. > > And it doesn't make sense to generate a wrapper for Foo in the first > place because Foo is final, and so function bar() cannot be overridden > anyway. May be you are right, I should think about it. > In the long term, I guess the proper fix is to not create wrappers for > final classes. There is no such definition in C++ as "final class". Private constructor is "public" for a function or another class. ( friend ) > Is there a short-term workaround for this problem? Try this: from pygccxml import declarations mb.mem_fun('bar').virtuality = declarations.FUNCTION_VIRTUALITY_TYPES.NOT_VIRTUAL For me it generated next code: BOOST_PYTHON_MODULE(final_classes){ bp::class_< final_classes::Foo, boost::noncopyable >( "Foo", "documentation", bp::no_init ) .def( "bar" , &::final_classes::Foo::bar , "documentation" ); } Anyway I committed new test case "final_classes_tester.py". > I tried using finalize() from goodie_utils but that didn't work unfortunately. Basically this is the code contributed by other developers and I don't support it. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ |
From: Julian S. <jul...@rs...> - 2007-07-09 08:00:25
Attachments:
foo_bp.cpp
|
Hello, many thanks for your quick reply. Roman Yakovenko wrote: > On 7/9/07, Julian Scheid <jul...@rs...> wrote: >> I've run into a problem with Py++ (both with 0.9.0 and with trunk) when >> trying to expose a class like this: >> >> class Foo >> { >> public: >> virtual void bar() {} >> private: >> Foo() {} >> }; > > What compiler do you use? I just checked this on MSVC 7.1 and it works > fine. > I attach the generated code. That was a bad example - it actually compiles for me, too. But the following won't compile on g++ 3.x (tested 3.4.2, 3.4.1 and 3.3.1) with "base `Foo' with only non-default constructor in class without a constructor". It works fine on g++ 4.0.2 though... so maybe it's not something that needs to be fixed after all. class Foo { public: virtual void foo() {} private: Foo(bool) {} }; I've attached the generated code as well. But it looks like it's sort of a non-issue after all, sorry if I wasted your time. >> In the long term, I guess the proper fix is to not create wrappers for >> final classes. > > There is no such definition in C++ as "final class". Private > constructor is "public" for a function or another class. ( friend ) True, but wouldn't the private constructor have to be "public" from the point of view of the deriving class? If you take a closed API that uses private constructors like this, for example, it effectively means that you can't subclass the class in question short of tinkering with the header. I guess at any rate it would be great if Py++ could add a (simple) way to explicitly disable wrapper generation for a given class. >> Is there a short-term workaround for this problem? > > Try this: I'll give that a try, thanks again for your help! Julian |