[Cython] Problem with final cdef methods

Nikita Nemkin nikita at nemkin.ru
Thu Aug 29 08:24:08 CEST 2013


On Thu, 29 Aug 2013 11:03:01 +0600, Stefan Behnel <stefan_ml at behnel.de>  
wrote:

> I noticed two problems with final cdef methods. When overriding a normal
> cdef method with a final cdef method, you currently get a C compiler
> warning about a call with the wrong 'self' type, and when you call them
> before you declare them in your code, you get an error because the method
> is not forward declared.
>
> http://trac.cython.org/cython_trac/ticket/819
>
> I think this suggests that we should try to come up with a cleaner way to
> integrate this feature into the function overloading architecture rather
> than just remembering their cname and call that.

As your ticket mentions, there is a fundamental problem with method  
inheritance.
(and with the way Cython generates forward declarations...)

Any inherited method assumes 2 types simultaneously: the type of the base
method with 1st parameter being a base class pointer and the "actual" type
of the method with 1st parameter being derived class pointer.
1st type, stored in method's Entry.type, is essentially the vtable slot
type. It's used when virtual method calls a made. It's also used for  
generating
forward declarations and for casting in vtable init code.
2nd type (stored in CFuncDef node) is used ONLY to generate function
definition.

The mismatch between these 2 types is the root of the problem.
Before final methods were introduced, the 2nd ("actual") type was  
unimportant.
Method was cast to the vtable slot type in vtable init code and forgotten.
But final functions, bypassing vtable mechanic, rely soley on the 2nd type.

I have solved it for myself by storing BOTH types in the method entry
(Entry.type for the actual CFuncDef type and Entry.prev_type for the vtable
slot type). By using correct types in  
generate_exttype_final_methods_declaration()
and generate_exttype_vtable_init_code() the problem is avoided.
You can see the patch here  
https://github.com/nnemkin/cython/compare/final_subtypes
Notes for the patch:
* I removed a bit of wtf code from CFuncType.declaration_code,
   these changes are incidental to the problem you describe.
   (Strictly necessary parts are only the lines involving "prev_type").
* There is a disabled bug test named "inherited_final_method", you
   may want to remove/merge it with the test you modified.

I hope this helps.


Best regards,
Nikita Nemkin


More information about the cython-devel mailing list