Python 3 and isinstance(np.int64(42), int)
Hi! I just finished porting a large codebase to Python 3 (making it work on 2.6, 2.7 and 3.4). It wasn't that difficult, but one thing gave me a hard time and it was this: Python 2.7.9 (default, Apr 2 2015, 15:33:21) [GCC 4.9.2] on linux2 Type "help", "copyright", "credits" or "license" for more information.
a = np.zeros(7, int) n = a[3] type(n)
isinstance(n, int) True
With Python 3.4 you get False. I think I understand why (np.int64 is no longer a subclass of int). So, I did this instead: import numbers isinstance(n, numbers.Integral) which works fine (with numpy1.9). Is this the "correct" way or is there a better way to do it? I would imagine that a lot of code will break because of this  so it would be nice if isinstance(n, int) could be made to work the same way in 2 and 3, but I don't know if this is possible (or desirable). Jens Jørgen
On Wed, Jun 17, 2015 at 10:53 PM, Jens Jørgen Mortensen
type(n)
isinstance(n, int) True With Python 3.4 you get False. I think I understand why (np.int64 is no longer a subclass of int).
Yep, that's correct.
So, I did this instead:
import numbers isinstance(n, numbers.Integral)
which works fine (with numpy1.9). Is this the "correct" way or is there a better way to do it?
That's the correct way to check whether an arbitrary object is of some integerliketype, yes :). There are alternatives, and there's some argument that in Python, doing explicit type checks like this is usually a sign that one is doing something awkward, but that's a more general issue that it's hard to comment on here without more detail about what exactly you're trying to accomplish.
I would imagine that a lot of code will break because of this  so it would be nice if isinstance(n, int) could be made to work the same way in 2 and 3, but I don't know if this is possible (or desirable).
It's not possible, unfortunately. In py2, 'int' is a 32 or 64bit integer type, so we can arrange for numpy's int32 or int64 objects to be laid out the same in memory, so everything in python that expects an int (including C API functions) can handle a numpy int. In py3, 'int' is an arbitrary width integer bignum, like py2 'long', which is fundamentally different from int32 and int64 in both semantics and implementation. n  Nathaniel J. Smith  http://vorpus.org
In some cases calling operator.index(n) may yield the desired result. I like operator.index, but maybe it is just me :). That uses duck typing instead of instance checking to ask if it represents an integer. But it also has some awkward corner cases in numpy, since arrays with a single element (deprecation pending) and 0D arrays (will continue) say they are integers when asked that way.  Sebastian On Mi, 20150617 at 23:13 0700, Nathaniel Smith wrote:
On Wed, Jun 17, 2015 at 10:53 PM, Jens Jørgen Mortensen
wrote: type(n)
isinstance(n, int) True With Python 3.4 you get False. I think I understand why (np.int64 is no longer a subclass of int).
Yep, that's correct.
So, I did this instead:
import numbers isinstance(n, numbers.Integral)
which works fine (with numpy1.9). Is this the "correct" way or is there a better way to do it?
That's the correct way to check whether an arbitrary object is of some integerliketype, yes :). There are alternatives, and there's some argument that in Python, doing explicit type checks like this is usually a sign that one is doing something awkward, but that's a more general issue that it's hard to comment on here without more detail about what exactly you're trying to accomplish.
I would imagine that a lot of code will break because of this  so it would be nice if isinstance(n, int) could be made to work the same way in 2 and 3, but I don't know if this is possible (or desirable).
It's not possible, unfortunately. In py2, 'int' is a 32 or 64bit integer type, so we can arrange for numpy's int32 or int64 objects to be laid out the same in memory, so everything in python that expects an int (including C API functions) can handle a numpy int. In py3, 'int' is an arbitrary width integer bignum, like py2 'long', which is fundamentally different from int32 and int64 in both semantics and implementation.
n
Nathaniel Smith
In py3, 'int' is an arbitrary width integer bignum, like py2 'long', which is fundamentally different from int32 and int64 in both semantics and implementation.
Only when stored in an ndarray. An array scalar object does not need to care about the exact number of bits used for storage as long as the storage is large enough, which a python int always is. Sturla
On Wed, Jun 17, 2015 at 11:13 PM, Nathaniel Smith
there's some argument that in Python, doing explicit type checks like this is usually a sign that one is doing something awkward,
I tend to agree with that. On the other hand, numpy itself is kindof sortof statically typed. But in that case, if you need to know the type of an array  check the array's dtype. Also:
a = np.zeros(7, int) n = a[3] type(n)
I Never liked declaring numpy arrays with the python types like "int" or "float"  in numpy you usually care more about the type, so should simple use "int64" if you want a 64 bit int. And "float64" if you want a 64 bit float. Granted, pyton floats have always been float64 (on all platfroms??), and python ints used to a be a reasonable int type, but now that python ints are bigInts in py3, it really makes sense to be clear. And now that I think about it, in py2, int is 32 bit on win64 and 64 bit on *nix64  so you're really better off being explicit with your numpy arrays. CHB  Christopher Barker, Ph.D. Oceanographer Emergency Response Division NOAA/NOS/OR&R (206) 5266959 voice 7600 Sand Point Way NE (206) 5266329 fax Seattle, WA 98115 (206) 5266317 main reception Chris.Barker@noaa.gov
On Fri, Jun 19, 2015 at 4:15 PM, Chris Barker
On Wed, Jun 17, 2015 at 11:13 PM, Nathaniel Smith
wrote: there's some argument that in Python, doing explicit type checks like this is usually a sign that one is doing something awkward,
I tend to agree with that.
On the other hand, numpy itself is kindof sortof statically typed. But in that case, if you need to know the type of an array  check the array's dtype.
Also:
a = np.zeros(7, int) n = a[3] type(n)
I Never liked declaring numpy arrays with the python types like "int" or "float"  in numpy you usually care more about the type, so should simple use "int64" if you want a 64 bit int. And "float64" if you want a 64 bit float. Granted, pyton floats have always been float64 (on all platfroms??), and python ints used to a be a reasonable int type, but now that python ints are bigInts in py3, it really makes sense to be clear.
And now that I think about it, in py2, int is 32 bit on win64 and 64 bit on *nix64  so you're really better off being explicit with your numpy arrays.
a = np.zeros(7, int) a.dtype
being late checking some examples dtype('int32')
np.__version__ '1.9.2rc1' type(a[3])
a = np.zeros(7, int) a = np.array([888888888888888888]) a array([888888888888888888], dtype=int64)
a = np.array([888888888888888888888888888888888]) a array([888888888888888888888888888888888], dtype=object)
a = np.array([888888888888888888888888888888888], dtype=int) Traceback (most recent call last): File "
", line 1, in <module> a = np.array([888888888888888888888888888888888], dtype=int) OverflowError: Python int too large to convert to C long
Looks like we need to be a bit more careful now. Josef Python 3.4.3
CHB

Christopher Barker, Ph.D. Oceanographer
Emergency Response Division NOAA/NOS/OR&R (206) 5266959 voice 7600 Sand Point Way NE (206) 5266329 fax Seattle, WA 98115 (206) 5266317 main reception
Chris.Barker@noaa.gov
_______________________________________________ NumPyDiscussion mailing list NumPyDiscussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpydiscussion
participants (6)

Chris Barker

Jens Jørgen Mortensen

josef.pktd＠gmail.com

Nathaniel Smith

Sebastian Berg

Sturla Molden