Ipython: NumPy DeprecationWarning handled in strange way

Created on 6 Apr 2018  路  4Comments  路  Source: ipython/ipython

When performing an operation with NumPy 1.14 that appears to be deprecated, the warning seems to be tracking back to IPython or the IPython Kernel depending on context, which is a bit misleading. In the Jupyter Notebook, it adds a little extra text stating, This is separate from the ipykernel package so we can avoid doing imports until and trails off just like that (hence raising here first). Not sure if this is an issue in IPython, the IPython Kernel, or NumPy. Here is an MRE though.


Example:

In [1]: import numpy as np

In [2]: a = np.arange(24).reshape(1, 2, 3, 4)

In [3]: np.expand_dims(a.min(), a.ndim)
/zopt/conda2/envs/test/bin/ipython:1: DeprecationWarning: Both axis > a.ndim and axis < -a.ndim - 1 are deprecated and will raise an AxisError in the future.
  #!/zopt/conda2/envs/test/bin/python
Out[3]: array([0])



Environment:

name: test
channels:
- conda-forge
- defaults
dependencies:
- appnope=0.1.0=py36_0
- backcall=0.1.0=py_0
- blas=1.1=openblas
- ca-certificates=2018.1.18=0
- certifi=2018.1.18=py36_0
- decorator=4.2.1=py36_0
- ipython=6.3.1=py36_0
- ipython_genutils=0.2.0=py36_0
- jedi=0.11.1=py36_0
- libgfortran=3.0.0=0
- ncurses=5.9=10
- numpy=1.14.2=py36_blas_openblas_200
- openblas=0.2.20=7
- openssl=1.0.2n=0
- parso=0.1.1=py_0
- pexpect=4.4.0=py36_0
- pickleshare=0.7.4=py36_0
- pip=9.0.3=py36_0
- prompt_toolkit=1.0.15=py36_0
- ptyprocess=0.5.2=py36_0
- pygments=2.2.0=py36_0
- python=3.6.5=1
- readline=7.0=0
- setuptools=39.0.1=py36_0
- simplegeneric=0.8.1=py36_0
- six=1.11.0=py36_1
- sqlite=3.20.1=2
- tk=8.6.7=0
- traitlets=4.3.2=py36_0
- wcwidth=0.1.7=py36_0
- wheel=0.31.0=py36_0
- xz=5.2.3=0
- zlib=1.2.11=0

Most helpful comment

A PR I submitted to Python was merged, so this should be fixed in Python 3.8.

https://github.com/python/cpython/pull/6622

All 4 comments

Yup, this is a result of having __main__ represent two different things. It's trying to issue a warning for line 1 of your code entered interactively, which is run as part of the __main__ module. But the lines are coming from the other __main__ module - the file that Python ran to launch IPython, or to launch the kernel. So the text you see is the first line of that file (the This is separate... text is a docstring).

It's a bit messy and confusing, but it's never really been a big enough problem to be worth fixing.

I got curious and went to see what it would take to fix it. We could quite easily leave the code out of all warnings attributed to __main__, but that's a bit unsatisfactory. Showing the correct code is impossible for IPython, as far as I can tell, because the warnings module looks up code in its own peculiar idiom.

Tracebacks and pdb find the file by doing:

frame.f_code.co_filename

Warnings finds the file by doing the equivalent of:

frame.f_globals.get('__file__', sys.argv[0])

We give each input a unique fake filename for its code, so it can be looked up for tracebacks. But they all have to share the global namespace, so I don't think we can distinguish them for warnings at the moment. I've just commented about this on an ancient Python issue.

A PR I submitted to Python was merged, so this should be fixed in Python 3.8.

https://github.com/python/cpython/pull/6622

Thanks @takluyver!

Was this page helpful?
0 / 5 - 0 ratings