Repository: ipython/ipython

Issue:
whos under pypy1.6
magic who command works, but 'whos' gives an error that has to do with numpy

/IPython/core/magic.py in magic_whos(self, parameter_s) line 870
AttributeError: 'module' object has no attribute 'ndarray'

This version of pypy has a trial version of numpy that only has 1d arrays, not ndarray.



Discussion:
There's a troubling implication that we have to allow that numpy may not really be numpy.  We check for numpy in quite a few places, I think, because it's such a basic package.

I guess to be friendly to PyPy, we would have to make sure that we never consider numpy present in that context.

I don't really think PyPy should be calling this library 'numpy', at least until it's substantially equivalent to numpy. I know quite a few of the tests break on PyPy because of this as well.

True, it would probably be better if they left it as micronumpy while they are in these extremely early stages in development, and especially if their goal is not 100% API coverage.

In any case, I acked the source and we really don't deal with numpy that much, except in the parallel code where PyPy support is a long way off (if ever), given that it all starts with pyzmq.

Changing this whos check is a two-line fix.  magic_precision also checks for numpy assuming it's real, and can be made to be a more direct check for the function it calls.

There was a GSoC project to allow Cython to produce pure Python output with ctypes for compiled libraries, which would work on PyPy. It didn't get finished, but hopefully someone will pick it up.

The simplest fix, at least in magic.py is to set ndarry_type to None if there is an AttributeError.  If the user does create a pypy numpy variable, it will be displayed like 'Everything else'.  I have fudged summary information for numarray type (e.g. there's no size or itemsize attribute), but that's aiming at a moving target.

I agree that it would cleaner to not even import numpy if the user has not already done so, and created a ndarray variable, but I'm not sure if that can be done simply and cleanly (without risk of breaking something else).

Yes, I think we will go with the more explicit check for the attribute, it's easy enough.


Resolving patch:
diff --git a/IPython/core/magic.py b/IPython/core/magic.py
--- a/IPython/core/magic.py
+++ b/IPython/core/magic.py
@@ -861,19 +861,15 @@ def magic_whos(self, parameter_s=''):
         # for these types, show len() instead of data:
         seq_types = ['dict', 'list', 'tuple']
 
-        # for numpy/Numeric arrays, display summary info
-        try:
-            import numpy
-        except ImportError:
-            ndarray_type = None
-        else:
-            ndarray_type = numpy.ndarray.__name__
-        try:
-            import Numeric
-        except ImportError:
-            array_type = None
-        else:
-            array_type = Numeric.ArrayType.__name__
+        # for numpy arrays, display summary info
+        ndarray_type = None
+        if 'numpy' in sys.modules:
+            try:
+                from numpy import ndarray
+            except ImportError:
+                pass
+            else:
+                ndarray_type = ndarray.__name__
 
         # Find all variable names and types so we can figure out column sizes
         def get_vars(i):
@@ -918,7 +914,7 @@ def type_name(v):
             print vformat.format(vname, vtype, varwidth=varwidth, typewidth=typewidth),
             if vtype in seq_types:
                 print "n="+str(len(var))
-            elif vtype in [array_type,ndarray_type]:
+            elif vtype == ndarray_type:
                 vshape = str(var.shape).replace(',','').replace(' ','x')[1:-1]
                 if vtype==ndarray_type:
                     # numpy


Test patch: