Discussion:
[Numpy-discussion] Python 3 and isinstance(np.int64(42), int)
Jens Jørgen Mortensen
2015-06-18 05:53:31 UTC
Permalink
Hi!

I just finished porting a large code-base 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)
<type 'numpy.int64'>
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 numpy-1.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
Nathaniel Smith
2015-06-18 06:13:39 UTC
Permalink
On Wed, Jun 17, 2015 at 10:53 PM, Jens Jørgen Mortensen
Post by Jens Jørgen Mortensen
type(n)
<type 'numpy.int64'>
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.
Post by Jens Jørgen Mortensen
import numbers
isinstance(n, numbers.Integral)
which works fine (with numpy-1.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
integer-like-type, 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.
Post by Jens Jørgen Mortensen
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 64-bit
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
Sebastian Berg
2015-06-18 08:38:43 UTC
Permalink
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 Wed, Jun 17, 2015 at 10:53 PM, Jens JÞrgen Mortensen
Post by Jens Jørgen Mortensen
type(n)
<type 'numpy.int64'>
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.
Post by Jens Jørgen Mortensen
import numbers
isinstance(n, numbers.Integral)
which works fine (with numpy-1.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
integer-like-type, 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.
Post by Jens Jørgen Mortensen
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 64-bit
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
Sturla Molden
2015-06-18 11:55:46 UTC
Permalink
Post by 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
Chris Barker
2015-06-19 20:15:26 UTC
Permalink
Post by 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 kind-of sort-of statically typed. But in
that case, if you need to know the type of an array -- check the array's
dtype.
Post by Nathaniel Smith
a = np.zeros(7, int)
n = a[3]
type(n)
<type 'numpy.int64'>

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) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

***@noaa.gov
j***@gmail.com
2015-06-23 16:33:11 UTC
Permalink
Post by Chris Barker
Post by 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 kind-of sort-of statically typed. But
in that case, if you need to know the type of an array -- check the array's
dtype.
Post by Nathaniel Smith
a = np.zeros(7, int)
n = a[3]
type(n)
<type 'numpy.int64'>
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.
being late checking some examples
Post by Chris Barker
Post by Nathaniel Smith
a = np.zeros(7, int)
a.dtype
dtype('int32')
Post by Chris Barker
Post by Nathaniel Smith
np.__version__
'1.9.2rc1'
Post by Chris Barker
Post by Nathaniel Smith
type(a[3])
<class 'numpy.int32'>
Post by Chris Barker
Post by Nathaniel Smith
a = np.zeros(7, int)
a = np.array([888888888888888888])
a
array([888888888888888888], dtype=int64)
Post by Chris Barker
Post by Nathaniel Smith
a = np.array([888888888888888888888888888888888])
a
array([888888888888888888888888888888888], dtype=object)
Post by Chris Barker
Post by Nathaniel Smith
a = np.array([888888888888888888888888888888888], dtype=int)
Traceback (most recent call last):
File "<pyshell#10>", 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
Post by Chris Barker
-CHB
--
Christopher Barker, Ph.D.
Oceanographer
Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception
_______________________________________________
NumPy-Discussion mailing list
http://mail.scipy.org/mailman/listinfo/numpy-discussion
Loading...