Metaclass .pxd: How should I implement __eq__()?

269 views
Skip to first unread message

Mike Pennington

unread,
Jan 19, 2015, 2:55:30 PM1/19/15
to cython...@googlegroups.com
I am trying to augment an existing python source with a cython .pxd; however, I keep hitting a wall with __eq__() in the .pxd.  I know I need to use __richcmp__(), but the details of doing this are not obvious...

 - If I use "cdef inline __richcmp__(Japan_Car_ABC self, Japan_Car_ABC other):", cython complains that "Special methods must be declared with 'def', not 'cdef'"
 - If I use "def __richcmp__(Japan_Car_ABC self, Japan_Car_ABC other):", cython complains that "function definition in pxd file must be declared 'cdef inline'"

Details and code are shown in this question....

http://stackoverflow.com/questions/28023151/cython-metaclass-pxd-how-should-i-implement-eq

Is there a way to fix this without rewriting everything into a .pyx file?

Apologies for cross-posting from Stack Overflow, but I have a feeling that this might be a problem for the list...

Thoughts?
\mike

Nils Bruin

unread,
Jan 19, 2015, 4:45:41 PM1/19/15
to cython...@googlegroups.com, penning...@gmail.com, mi...@pennington.net
On Monday, January 19, 2015 at 11:55:30 AM UTC-8, Mike Pennington wrote:
 - If I use "cdef inline __richcmp__(Japan_Car_ABC self, Japan_Car_ABC other):", cython complains that "Special methods must be declared with 'def', not 'cdef'"
 - If I use "def __richcmp__(Japan_Car_ABC self, Japan_Car_ABC other):", cython complains that "function definition in pxd file must be declared 'cdef inline'"
 
For one thing, the required signature is "def __richcmp__(self, other, op), where "op" automatically gets treated as "int". I would expect that "self" is implicitly typed to be "Japan_Car_ABC" but "other" will just be "object", since that is what the python API specifies.

However, the error that you get seems to suggest that in a "pxd" you cannot declare special methods. That makes sense, since they are not part of the C-API of the class. They declare a method that ends up in a slot in the PyType data structure. Furthermore, unlike "inline" code which does need to be available in the header file, this needs to be compiled as an actual function, so it belongs in the implementing file.

For cythonization of "pure python" files, cython would need to recognize the (for python) special methods __eq__, __ne__, etc.; compile them properly, and provide a proper dispatching __richcmp__ for them. It wouldn't surprise me if that weren't available yet, especially because people can implement these __eq__ functions etc. with all kinds of decorators.

Mike Penningotn

unread,
Jan 19, 2015, 8:02:08 PM1/19/15
to cython...@googlegroups.com, penning...@gmail.com, mi...@pennington.net


On Monday, January 19, 2015 at 3:45:41 PM UTC-6, Nils Bruin wrote:
 
For one thing, the required signature is "def __richcmp__(self, other, op), where "op" automatically gets treated as "int". I would expect that "self" is implicitly typed to be "Japan_Car_ABC" but "other" will just be "object", since that is what the python API specifies.


Thank you for explaining __richcmp__(), I'll be sure to include op.
 
However, the error that you get seems to suggest that in a "pxd" you cannot declare special methods. That makes sense, since they are not part of the C-API of the class. They declare a method that ends up in a slot in the PyType data structure. Furthermore, unlike "inline" code which does need to be available in the header file, this needs to be compiled as an actual function, so it belongs in the implementing file.

Is there someone who can definitely confirm whether you can or can't declare special methods in a pxd?  If you truly can't do it, then the compiler should warn me thusly...  I will file a bug on trac if someone can confirm.
 

For cythonization of "pure python" files, cython would need to recognize the (for python) special methods __eq__, __ne__, etc.; compile them properly, and provide a proper dispatching __richcmp__ for them. It wouldn't surprise me if that weren't available yet, especially because people can implement these __eq__ functions etc. with all kinds of decorators.

Can you give a pointer to docs for how I might use decorators to accomplish what I need? 

Nils Bruin

unread,
Jan 20, 2015, 1:11:32 PM1/20/15
to cython...@googlegroups.com, penning...@gmail.com, mi...@pennington.net
On Monday, January 19, 2015 at 5:02:08 PM UTC-8, Mike Penningotn wrote:

Can you give a pointer to docs for how I might use decorators to accomplish what I need? 

I'm not so sure that you can. What I was referring to is that only implementing a few rich comparison methods and then letting a class decorator figure out the rest, as in https://docs.python.org/2/library/functools.html#functools.total_ordering seems to be a recommended approach by the python documentation, so if Cython were to be extended to construct a __richcmp__ from __eq__, __lt__ methods on a python class then it would need to be prepared to handle this somehow. That makes the fastest approach, inlining the definitions of the __eq__, __lt__ methods into a __richcmp__ template, rather complicated and perhaps impossible.

Reply all
Reply to author
Forward
0 new messages