Cython 3.0.5 rejects a float for an np.npy_intp parameter

61 views
Skip to first unread message

Jerry Morrison

unread,
Nov 2, 2023, 2:06:05 AM11/2/23
to cython-users
This seems to be a behavior change:
    An `np.npy_intp` function parameter rejects a float value in Cython 3.0.0 - 3.05 vs. truncating the float to an integer in Cython 0.29.34.

Example: numpy.random.multinomial(self, np.npy_intp n, object pvals, size=None)

----- Test case -----
    import numpy as np
    np.random.multinomial(20.0, [1/6.]*6, size=1)
TypeError: 'float' object cannot be interpreted as an integer
----------

Because Numpy 1.26.* uses Cython 3, this is an undocumented Numpy API change.

Q. Is it an intentional change or a Cython 3 bug?

Here's a small test case without Numpy:

----------
import numpy as np
cimport numpy as np

def func(int length):
    return length

def weird_func(np.npy_intp length):
    return length
----------
func(1.1)   returns 1
weird_func(1.1)   raises TypeError
----------

Thanks.

Stefan Behnel

unread,
Nov 2, 2023, 4:42:19 AM11/2/23
to cython...@googlegroups.com
Hi,

first of all, note that the NumPy bindings are now maintained by the NumPy
project, not by Cython:

https://github.com/numpy/numpy/blob/main/numpy/__init__.cython-30.pxd


Jerry Morrison schrieb am 02.11.23 um 06:57:
> This seems to be a behavior change:
> An `np.npy_intp` function parameter rejects a float value in Cython
> 3.0.0 - 3.05 vs. truncating the float to an integer in Cython 0.29.34.

"npy_intp" is declared as "Py_ssize_t", which uses the Python "__index__"
protocol for the conversion, not "__int__".

https://github.com/numpy/numpy/blob/7a4f6b0c11f9b5c13aa9e463a2a8f2c040a6daed/numpy/__init__.cython-30.pxd#L27


> Example: numpy.random.multinomial
> <https://github.com/numpy/numpy/blob/cdfbdf428d9df9c7119cecae323512a4cd3f57b7/numpy/random/mtrand.pyx#L4256>(self,
> np.npy_intp n, object pvals, size=None)
>
> ----- Test case -----
> import numpy as np
> np.random.multinomial(20.0, [1/6.]*6, size=1)
> TypeError: 'float' object cannot be interpreted as an integer
> ----------

This is to be expected. You'd probably want to use your own integer
conversion/rounding in your code to make sure that you get the integer
value that you want.

Stefan

Jerry Morrison

unread,
Nov 3, 2023, 1:29:21 AM11/3/23
to cython-users
Thanks. I am adding my own integer conversion for multinomial() but it's unclear which NumPy APIs changed in this way and whether it was intentional.

mtrand.pyi declares multinomial's argument n as type _ArrayLikeInt_co, while mtrand.pyx delcares it as np.npy_intp.

Reply all
Reply to author
Forward
0 new messages