Cython Metaclass.pxd: How do I implement `__eq __ ()`?

I am trying to expand an existing python source using cython .pxd , as Stefan Bechnel shows in slides 32 through 35 of "Using the Cython Compiler to Write Fast Python Code" .

As part of the exercise, I continue to hit the wall with the __eq__() method in my metaclass. I wish I could choose a simpler case to run Cython, but my production code is not so simple. I prepared a “minimal, complete example” to illustrate the problem ... see the code at the bottom of the question.

Story...

  • If I use cdef inline __richcmp__(Japan_Car_ABC self, Japan_Car_ABC other, int op): 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, int op): cython complains that function definition in pxd file must be declared 'cdef inline'

So cython gives me a confusing guide ...

Questions

  • I know that pure-python .pxd have limitations; defines __richcmp__() in my .pxd valid way to use .pxd to extend pure python?
  • If this is a valid way to use .pxd , how can I fix this to compile correctly?
  • If this is not true, can .pxd enhance my pure python meta-analysis without rewriting the entire metaclass in the .pyx file? (example: class Card in this project )

This is my .pxd ...

 ### File: car_abc.pxd # cython: infer_types=True cimport cython cdef class Japan_Car_ABC: cpdef public char* model cpdef public char* color def __richcmp__(Japan_Car_ABC self, Japan_Car_ABC other, int op): """Ref: http://docs.cython.org/src/userguide/special_methods.html#rich-comparisons""" if op==2: # op==2 is __eq__() in pure python if self.model==other.model: return True return False else: err_msg = "op {0} isn't implemented yet".format(op) raise NotImplementedError(err_msg) 

Informational

car_abc.py:

 ### File: car_abc.py from abc import ABCMeta class Japan_Car_ABC(object): __metaclass__ = ABCMeta def __init__(self, model="", color=""): self.model = model self.color = color def __eq__(self, other): if self.model==other.model: return True return False def __hash__(self): return hash(self.model) 

car.py:

 from car_abc import Japan_Car_ABC class Lexus(Japan_Car_ABC): def __init__(self, *args, **kwargs): bling = kwargs.pop("bling", True) # bling keyword (default: True) super(Lexus, self).__init__(*args, **kwargs) self.bling = bling class Toyota(Japan_Car_ABC): def __init__(self, *args, **kwargs): super(Toyota, self).__init__(*args, **kwargs) if __name__=="__main__": gloria_car = Lexus(model="ES350", color="White") jeff_car = Toyota(model="Camry", color="Silver") print("gloria_car.model: {0}".format(gloria_car.model)) print("jeff_car.model: {0}".format(jeff_car.model)) print("gloria_car==jeff_car: {0}".format(gloria_car==jeff_car)) 

setup.py:

 from distutils.core import setup from distutils.extension import Extension from Cython.Distutils import build_ext ext_modules = [Extension("car_abc", ["car_abc.py"]), #Extension("car", ["car.py"]), ] setup( name = "really build this thing", cmdclass = {'build_ext': build_ext}, ext_modules = ext_modules ) 
+7
python metaclass cython
source share
1 answer

The simple answer (obtained from Nils Bruin via cython-users ) is that pxd cannot be used to implement methods (e.g. __richcmp__() ). Since I use a metaclass, I need to port my code to .pyx, so I can implement __richcmp__() and other special cython methods.

+3
source share

All Articles