[Pyrex] pyrexc error: Python object cannot be converted to __mpz_struct (?)
Heiko Wundram
heikowu at ceosg.de
Thu May 27 17:25:22 CEST 2004
Hi all!
I'm trying to wrap the Gnu Multiprecision Integer library for code I'm
creating, in an effort to maximize performance especially for public/private
key encryption. (the mpz module of Python doesn't export a third of the
functionality GMP actually has to offer, such as _fast_ miller-rabin testing,
which is available as of GMP 4.0, etc.)
I'm trying to write the wrapper using Pyrex, and at the moment I'm stuck at
the following:
I'm trying to implement the __add__ method, which returns a new GMP object,
which contains the two numbers, added using the mpz_* methods. For this, I
create a new GMP object (retv = GMP()), whose private member mpznumber
contains the appropriate MPZ structure. Now, when I try to compile the
following code fragment, pyrexc spits out the following error messages:
/home/heiko/projects/Crypto/Utility.pyx:103:34: Cannot convert Python object
to '__mpz_struct (*)'
/home/heiko/projects/Crypto/Utility.pyx:110:31: Cannot convert Python object
to '__mpz_struct (*)'
From what I gather from these lines, I think pyrexc thinks that retv.mpznumber
points to a Python object, whereas it simply is a reference to the structure
member mpznumber of the class structure. It doesn't complain about
_otherGMP.mpznumber, which resolves similarly, as the cdef definition for the
two of them is pretty much equal.
The code:
cdef class GMP:
cdef mpz_t mpznumber
<!-- init snipped -->
def __add__(self,other):
cdef GMP _otherGMP
cdef unsigned int _otherint
cdef GMP retv
retv = GMP()
try:
_otherint = other
mpz_add_ui(retv.mpznumber,self.mpznumber,_otherint)
return retv
except:
pass
try:
_otherGMP = other
mpz_add(retv.mpznumber,self.mpznumber,
_otherGMP.mpznumber)
return retv
except:
raise TypeError, "Invalid type to add."
What is wrong here?
Oh, and by the way, I've read that e.g. you shouldn't call PyInt_ToLong()
(which is how _otherint = other is resolved) before having checked the type
of the passed in python object. I've not found a sane way (except "if
isinstance(...)", which expands to huge amounts of runtime python code,
whereas a simple PyInt_Check() should suffice) to check the type of an
incoming object, when the method accepts more than a single type. Do I need
to declare PyInt_Check() at cdef scope modulewide, and then call it myself,
or is there a simple way to have exactly this typeswitching code generated by
Pyrex (I've found no mention of this in the documentation)?
Thanks for any hint!
Heiko.
More information about the Pyrex
mailing list