[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