-
-
Notifications
You must be signed in to change notification settings - Fork 12k
Description
This has come up before, but I'm not sure we have a canonical issue.
Historically in python 2:
builtins.intis mapped tonp.int_(Clong), sincebuiltins.intis stored as a Clongbuiltins.longis mapped tonp.longlong(Clong long), sincebuiltins.longis infinite precision and that's the largest available integer type
# python 2.7
>>> np.dtype(int).char
'l'
>>> np.dtype(long).char
'q'Note the above output only reflects the state of windows - other platforms have sizeof(long) == sizeof(long long), so the distinction isn't important.
In python 3, builtins.int has been removed, and builtins.long has been renamed to __builtins__.int. Yet:
# python 3.5
>>> new_long = int
>>> np.dtype(new_long).char
'l' # smaller than it was on python 2This means that python code translated from 2 to 3 by replacing long with int will start behaving differently:
# python 2
>>> np.array(10**10, dtype=long)
array(10000000000L, dtype=int64)# python 3 translation
>>> np.array(10**10, dtype=int)
OverflowError: Python int too large to convert to C longSince this affects users transitioning from 2 to 3, I think it's important that we get it fixed in 1.16, which will be the last version that transitioning users can test both version of python against.
The current implementation, introduced in aa7be88 by @pv, is:
#if !defined(NPY_PY3K)
if (obj == (PyObject *)(&PyInt_Type)) {
check_num = NPY_LONG;
}
else if (obj == (PyObject *)(&PyLong_Type)) {
check_num = NPY_LONGLONG;
}
#else
if (obj == (PyObject *)(&PyLong_Type)) {
check_num = NPY_LONG;
}
#endifI'd propose it should have been:
#if !defined(NPY_PY3K)
if (obj == (PyObject *)(&PyInt_Type)) {
check_num = NPY_LONG;
}
else
#endif
if (obj == (PyObject *)(&PyLong_Type)) {
check_num = NPY_LONGLONG;
}Ie, treating PyLong_Type in python 3 just as we always did in python 2.