The documentation here is a bit confusing as it assumes you are familiar with using __new__ and __init__ .
The __cinit__ method __cinit__ roughly equivalent to the __new__ method in Python. *
Like __new__ , __cinit__ not called by your super().__init__ ; it is called before Python even gets into your subclass __init__ . The reason __cinit__ must be the signature processing of your subclass __init__ . Exactly the same reason __new__ does.
If your subclass explicitly calls super().__init__ , which again looks for the __init__ method in the superclass, for example __new__ , and __cinit__ not __init__ . So, if you have not defined __init__ yet, it will go to object .
You can see the sequence with the following code.
cinit.pyx:
cdef class Foo: def __cinit__(self, a, b, *args, **kw): print('Foo.cinit', a, b, args, kw) def __init__(self, *args, **kw): print('Foo.init', args, kw)
init.py:
import pyximport; pyximport.install() import cinit class Bar(cinit.Foo): def __new__(cls, *args, **kw): print('Bar.new', args, kw) return super().__new__(cls, *args, **kw) def __init__(self, a, b, c, d): print('Bar.init', a, b, c, d) super().__init__(a, b, c, d) b = Bar(1, 2, 3, 4)
When you start, you will see something like:
Bar.new (1, 2, 3, 4) {} Foo.cinit 1 2 (3, 4) {} Bar.init 1 2 3 4 Foo.init (1, 2, 3, 4) {}
So, the correct fix here depends on what you are trying to do, but this is one of the following:
- Add the
__init__ method to the Cython base class. - Delete the entire
super().__init__ . - Modify
super().__init__ to not pass any parameters. - Add the appropriate
__new__ method to the Python subclass.
I suspect that in this case you need 2.
* It is worth noting that __cinit__ definitely not identical to __new__ . Instead of getting the cls parameter, you get a partially constructed self object (where you can trust __class__ and C attributes, but not Python attributes or methods), the __new__ methods of all classes in the MRO have already been called before any __cinit__ ; __cinit__ your databases is automatically called automatically, and not manually; You cannot return another object than the one that was requested; etc. It is just that he called before __init__ and expected passing through parameters, just like __new__ .