Console introspection helpers and third-party calls to get_ipython() · Issue #25036 · pandas-dev/pandas (original) (raw)
This came up in explosion/spaCy/issues/3208 (and by proxy, jupyter/notebook#4369 and fastai/fastai#1531) and I've tracked it down to an issue with the way the IPython config is accessed.
If a third-party library or user code accesses nested properties in get_ipython()
before, say, printing a dataframe, the user will see a very confusing and very cryptic error in the pandas.io.formats.console.in_qtconsole
helper.
This isn't really pandas' fault, and we'll also be shipping a workaround for this in spaCy with the next version. But it might be worth adding a small fix to pandas as well, just to prevent similar interactions with other libraries and user code – especially considering that the methods are deprecated and not even needed for IPython 3+.
Also just wanted to let you know, in case others end up reporting this problem here.
Code Sample, a copy-pastable example if possible
Consider this minimal example, executed in a Jupyter notebook:
In[1]:
def test(): # This is what's executed in pandas.io.formats.console.in_qtconsole # and every time the user wants to output a dataframe ip = get_ipython() front_end = (ip.config.get('KernelApp', {}).get('parent_appname', "") or ip.config.get('IPKernelApp', {}).get('parent_appname', "")) front_end.lower()
In[2]:
test()
In[3]:
This is what another third-party package or user code might be running – for instance
we had this in spaCy in the global scope to check the environment for our visualizers
(this used to be the recommended way to detect an IPython environment)
cfg = get_ipython().config cfg['IPKernelApp']['parent_appname']
In[4]:
test()
Problem description
The last cell raises the following error:
<ipython-input-1-d52cc3b6c907> in test()
3 ip = get_ipython()
4 front_end = (ip.config.get('KernelApp', {}).get('parent_appname', "") or ip.config.get('IPKernelApp', {}).get('parent_appname', ""))
----> 5 front_end.lower()
AttributeError: 'LazyConfigValue' object has no attribute 'lower'
So in a real life scenario, the user renders a dataframe, then imports spaCy or any other package that happens to access the IPython config in the root, renders the dataframe again and sees this error.
Expected Output
No error. Maybe there's a way to skip the call to is_qtconsole
in DataFrame._repr_html
if it's not relevant to the user's IPython version?
Output of pd.show_versions()
INSTALLED VERSIONS
commit: None
python: 3.7.0.final.0
python-bits: 64
OS: Darwin
OS-release: 18.2.0
machine: x86_64
processor: i386
byteorder: little
LC_ALL: en_US.UTF-8
LANG: en_US.UTF-8
LOCALE: en_US.UTF-8
pandas: 0.24.0
pytest: None
pip: 10.0.1
setuptools: 39.0.1
Cython: None
numpy: 1.16.0
scipy: None
pyarrow: None
xarray: None
IPython: 7.2.0
sphinx: None
patsy: None
dateutil: 2.7.5
pytz: 2018.9
blosc: None
bottleneck: None
tables: None
numexpr: None
feather: None
matplotlib: None
openpyxl: None
xlrd: None
xlwt: None
xlsxwriter: None
lxml.etree: None
bs4: None
html5lib: None
sqlalchemy: None
pymysql: None
psycopg2: None
jinja2: 2.10
s3fs: None
fastparquet: None
pandas_gbq: None
pandas_datareader: None
gcsfs: None