Repository: spyder-ide/spyder

Issue:
Calltips in IPython console are empty but work in qtconsole
<!--- **PLEASE READ:** When submitting here, please ensure you've completed the following checklist and checked the boxes to confirm. Issue reports without it may be closed. Thanks! --->

### Issue Report Checklist

* [ x] Searched the [issues page](https://github.com/spyder-ide/spyder/issues?q=is%3Aissue) for similar reports
* [ x] Read the relevant sections of the [Spyder Troubleshooting Guide](https://github.com/spyder-ide/spyder/wiki/Troubleshooting-Guide-and-FAQ) and followed its advice
* [x ] Reproduced the issue after updating with ``conda update spyder`` (or ``pip``, if not using Anaconda)
* [x ] Could not reproduce inside ``jupyter qtconsole`` (if console-related)
* [] Tried basic troubleshooting (if a bug/error)
    * [x ] Restarted Spyder
    * [x] Reset preferences with ``spyder --reset``
    * [ ] Reinstalled the latest version of [Anaconda](https://www.anaconda.com/download/)
    * [ ] Tried the other applicable steps from the Troubleshooting Guide
* [ ] Completed the **Problem Description**, **Steps to Reproduce** and **Version** sections below


## Problem Description
Jupyter qtconsole displays docstrings while spyder 4.0.0 b2 instelled in the same environment
does not, which I expected.


### What steps reproduce the problem?

1. import numpy as np
2. numpy.abs(

### What is the expected output? What do you see instead?
Expected to see docstring as in jupyter qtconsole:
![Screenshot from 2019-06-07 10-02-22](https://user-images.githubusercontent.com/9726401/59093453-e15b1880-890b-11e9-8599-74da558fb4b5.png)

Instead I see an empty box:

![Screenshot from 2019-06-07 10-03-27](https://user-images.githubusercontent.com/9726401/59093446-ddc79180-890b-11e9-93eb-86e181983a30.png)

All run from the same python 3.7 env (see below for conda list

### Paste Traceback/Error Below (if applicable)
<!--- Copy from error dialog or View > Panes > Internal Console --->

```python-traceback

PASTE TRACEBACK HERE

```

## Versions

Python 3.7.2 64-bit | Qt 5.9.7 | PyQt5 5.9.2 | Linux 4.15.0-51-generic 

* Spyder version: Spyder 4.0.0b2 
* Python version: 
* Qt version: 
* PyQt version: 
* Operating System name/version:  Mint 19.1

### Dependencies
<!--- Please go to the menu entry Help > Dependencies,
press the Copy to clipboard button and paste below --->

```
pygments >=2.0     :  2.2.0 (OK)
qdarkstyle >=2.6.4 :  2.6.8 (OK)
sphinx >=0.6.6     :  2.0.1 (OK)
psutil >=0.3       :  5.6.1 (OK)
pyls >=0.19.0;<0.25:  0.24.0 (OK)
nbconvert >=4.0    :  5.5.0 (OK)
pandas >=0.13.1    :  None (NOK)
numpy >=1.7        :  1.15.1 (OK)
sympy >=0.7.3      :  None (NOK)
cython >=0.21      :  None (NOK)
qtconsole >=4.2.0  :  4.4.4 (OK)
IPython >=4.0      :  7.5.0 (OK)
matplotlib >=2.0.0 :  3.0.2 (OK)
pylint >=0.25      :  2.3.1 (OK)
```

<details>
(bjorn37) bjorn@Tp:~/Desktop$ conda list
# packages in environment at /home/bjorn/anaconda3/envs/bjorn37:
#
# Name                    Version                   Build  Channel
alabaster                 0.7.12                   py37_0    defaults
appdirs                   1.4.3                      py_1    conda-forge
arrow                     0.13.1                   py37_0    defaults
asn1crypto                0.24.0                   py37_0    defaults
astroid                   2.2.5                    py37_0    defaults
atk                       2.25.90           hb9dd440_1002    conda-forge
atomicwrites              1.2.1                    py37_0    defaults
attrs                     18.1.0                     py_1    conda-forge
automat                   0.7.0                    py37_0    defaults
autopep8                  1.4.4                      py_0    defaults
babel                     2.6.0                    py37_0    defaults
backcall                  0.1.0                      py_0    conda-forge
bandwagon                 0.1.4                    pypi_0    pypi
bcrypt                    3.1.6            py37h7b6447c_0    defaults
beautifulsoup4            4.7.1                    py37_1    defaults
binaryornot               0.4.4                      py_1    conda-forge
bio-info-questions        0.0.8                     dev_0    <develop>
biopython                 1.72                     pypi_0    pypi
blas                      1.0                         mkl    defaults
bleach                    2.1.4                      py_1    conda-forge
bzip2                     1.0.6                h470a237_2    conda-forge
ca-certificates           2019.5.15                     0    defaults
cairo                     1.16.0            ha4e643d_1000    conda-forge
certifi                   2019.3.9                 py37_0    defaults
cffi                      1.11.5           py37h5e8e0c9_1    conda-forge
chardet                   3.0.4                    pypi_0    pypi
click                     7.0                      py37_0    defaults
cloudpickle               0.8.1                      py_0    defaults
constantly                15.1.0                     py_0    conda-forge
cookiecutter              1.6.0                 py37_1000    conda-forge
coverage                  4.5.1            py37h14c3975_0    defaults
coveralls                 1.5.0                      py_0    conda-forge
cryptography              2.6.1            py37h1ba5d50_0    defaults
cryptography-vectors      2.3                      py37_1    conda-forge
cycler                    0.10.0                     py_1    conda-forge
dbus                      1.13.6               he372182_0    conda-forge
decorator                 4.3.0                      py_0    conda-forge
defusedxml                0.6.0                      py_0    defaults
dnachisel                 1.2                      pypi_0    pypi
docopt                    0.6.2                      py_1    conda-forge
docutils                  0.14                     py37_0    defaults
entrypoints               0.2.3                    py37_2    defaults
expat                     2.2.5                hfc679d8_1    conda-forge
ezodf                     0.3.2                      py_2    conda-forge
filelock                  3.0.10                   py37_0    defaults
flametree                 0.1.10                   pypi_0    pypi
fontconfig                2.13.1            he4413a7_1000    conda-forge
freetype                  2.9.1                h6debe1e_1    conda-forge
future                    0.17.1                   py37_0    defaults
gdk-pixbuf                2.36.12           h49783d7_1002    conda-forge
gettext                   0.19.8.1                      0    conda-forge
glib                      2.58.3            hf63aee3_1001    conda-forge
gmp                       6.1.2                hfc679d8_0    conda-forge
gobject-introspection     1.58.2          py37h2da5eee_1000    conda-forge
graphite2                 1.3.13            hf484d3e_1000    conda-forge
gst-plugins-base          1.14.4            hdf3bae2_1001    conda-forge
gstreamer                 1.14.4            h66beb1c_1001    conda-forge
gtk2                      2.24.31           hb68c50a_1001    conda-forge
harfbuzz                  2.4.0                h37c48d4_0    conda-forge
html5lib                  1.0.1                      py_0    conda-forge
hyperlink                 17.3.1                     py_0    conda-forge
icu                       58.2                 hfc679d8_0    conda-forge
idna                      2.7                      py37_2    conda-forge
imagesize                 1.1.0                    py37_0    defaults
incremental               17.5.0                     py_0    conda-forge
intel-openmp              2018.0.3                      0    defaults
ipdb                      0.12                       py_0    conda-forge
ipykernel                 5.1.0            py37h39e3cac_0    defaults
ipynb                     0.5.1                    pypi_0    pypi
ipython                   7.5.0            py37h39e3cac_0    defaults
ipython_genutils          0.2.0                      py_1    conda-forge
ipywidgets                7.4.2                    py37_0    defaults
isort                     4.3.17                   py37_0    defaults
jedi                      0.13.3                   py37_0    defaults
jeepney                   0.4                      py37_0    defaults
jinja2                    2.10                       py_1    conda-forge
jinja2-time               0.2.0                      py_2    conda-forge
jpeg                      9c                   h470a237_0    conda-forge
jsonschema                2.6.0                    py37_0    defaults
jupyter                   1.0.0                      py_1    conda-forge
jupyter_client            5.2.4                    py37_0    defaults
jupyter_console           6.0.0                    py37_0    defaults
jupyter_core              4.4.0                      py_0    conda-forge
keyring                   18.0.0                   py37_0    defaults
kiwisolver                1.0.1            py37h2d50403_2    conda-forge
lazy-object-proxy         1.3.1            py37h14c3975_2    defaults
libedit                   3.1.20181209         hc058e9b_0    defaults
libffi                    3.2.1                hfc679d8_4    conda-forge
libgcc-ng                 8.2.0                hdf63c60_1    defaults
libgfortran-ng            7.2.0                hdf63c60_3    conda-forge
libglu                    9.0.0             hf484d3e_1000    conda-forge
libiconv                  1.15                 h470a237_2    conda-forge
libpng                    1.6.35               ha92aebf_0    conda-forge
libsodium                 1.0.16                        0    conda-forge
libstdcxx-ng              8.2.0                hdf63c60_1    defaults
libtiff                   4.0.10            h648cc4a_1001    conda-forge
libuuid                   2.32.1               h470a237_0    conda-forge
libxcb                    1.13                 h470a237_2    conda-forge
libxml2                   2.9.9                he19cac6_0    defaults
libxslt                   1.1.33               h7d1a2b0_0    defaults
lxml                      4.3.3            py37hefd8a0e_0    defaults
markupsafe                1.0              py37h470a237_1    conda-forge
matplotlib                3.0.2            py37h5429711_0    defaults
mccabe                    0.6.1                    py37_1    defaults
mistune                   0.8.3                      py_0    conda-forge
mkl                       2018.0.3                      1    defaults
mkl_fft                   1.0.4            py37h4414c95_1    defaults
mkl_random                1.0.1            py37h4414c95_1    defaults
more-itertools            4.2.0                      py_0    conda-forge
mpldatacursor             0.6.2                    pypi_0    pypi
nb_conda                  2.2.1                    py37_0    defaults
nb_conda_kernels          2.2.1                    py37_0    defaults
nbconvert                 5.5.0                      py_0    defaults
nbformat                  4.4.0                      py_1    conda-forge
nbval                     0.9.1                      py_0    conda-forge
ncurses                   6.1                  hfc679d8_1    conda-forge
networkx                  2.3                        py_0    defaults
notebook                  5.7.8                    py37_0    defaults
notedown                  1.5.1                      py_0    conda-forge
numpy                     1.15.1                   pypi_0    pypi
numpy-base                1.15.1           py37h81de0dd_0    defaults
numpydoc                  0.9.1                      py_0    defaults
openssl                   1.1.1c               h7b6447c_1    defaults
packaging                 19.0                     py37_0    defaults
pandoc                    2.2.2                         1    conda-forge
pandoc-attributes         0.1.7                      py_1    conda-forge
pandocfilters             1.4.2                      py_1    conda-forge
pango                     1.40.14           h4ea9474_1004    conda-forge
paramiko                  2.4.2                    py37_0    defaults
parso                     0.3.1                      py_0    conda-forge
pcre                      8.43                 he6710b0_0    defaults
pexpect                   4.6.0                    py37_0    conda-forge
pickleshare               0.7.4                    py37_0    conda-forge
pint                      0.8.1                      py_1    conda-forge
pip                       18.0                     py37_1    conda-forge
pixman                    0.34.0            h14c3975_1003    conda-forge
pluggy                    0.11.0                     py_0    defaults
poyo                      0.4.2                      py_0    conda-forge
prettytable               0.7.2                    pypi_0    pypi
proglog                   0.1.9                    pypi_0    pypi
prometheus_client         0.3.0                      py_0    conda-forge
prompt_toolkit            2.0.9                    py37_0    defaults
psutil                    5.6.1            py37h7b6447c_0    defaults
pthread-stubs             0.4                  h470a237_1    conda-forge
ptyprocess                0.6.0                    py37_0    conda-forge
py                        1.6.0                      py_0    conda-forge
pyasn1                    0.4.4                      py_0    conda-forge
pyasn1-modules            0.2.1                      py_0    conda-forge
pycodestyle               2.5.0                    py37_0    defaults
pycparser                 2.18                       py_1    conda-forge
pydna                     3.0.0a45                  dev_0    <develop>
pydocstyle                3.0.0                    py37_0    defaults
pyfiglet                  0.8.post0                pypi_0    pypi
pyflakes                  2.1.1                    py37_0    defaults
pygenome                  2.0.0+4.gdf1a35a.dirty           dev_0    <develop>
pygments                  2.2.0                      py_1    conda-forge
pylint                    2.3.1                    py37_0    defaults
pynacl                    1.3.0            py37h7b6447c_0    defaults
pyopenssl                 18.0.0                   py37_0    conda-forge
pyparsing                 2.2.0                    pypi_0    pypi
pypubsub                  4.0.3                      py_0    conda-forge
pyqt                      5.9.2            py37hcca6a23_0    conda-forge
pysocks                   1.6.8                    py37_2    conda-forge
pytest                    4.5.0                    py37_0    defaults
pytest-cov                2.7.1                      py_0    conda-forge
python                    3.7.2                h0371630_0    defaults
python-codon-tables       0.1.8                    pypi_0    pypi
python-dateutil           2.7.3                      py_0    conda-forge
python-jsonrpc-server     0.1.2                      py_0    spyder-ide
python-language-server    0.24.0                   py37_0    spyder-ide
pytz                      2018.5                     py_0    conda-forge
pyyaml                    3.13             py37h470a237_1    conda-forge
pyzmq                     17.1.2           py37h14c3975_0    defaults
qdarkstyle                2.6.8                      py_0    spyder-ide
qt                        5.9.7                h52cfd70_1    conda-forge
qtawesome                 0.5.7                    py37_1    defaults
qtconsole                 4.4.4                      py_0    defaults
qtpy                      1.7.0                    py37_1    defaults
readline                  7.0               hf8c457e_1001    conda-forge
requests                  2.19.1                   pypi_0    pypi
requests-mock             1.5.2                      py_0    conda-forge
rope                      0.14.0                     py_0    defaults
scipy                     1.1.0            py37hfa4b5c9_1    defaults
secretstorage             3.1.1                    py37_0    defaults
send2trash                1.5.0                      py_0    conda-forge
service_identity          17.0.0                     py_0    conda-forge
setuptools                40.2.0                   py37_0    conda-forge
simplegeneric             0.8.1                      py_1    conda-forge
sip                       4.19.8          py37hf484d3e_1000    conda-forge
six                       1.11.0                   py37_1    conda-forge
snowballstemmer           1.2.1                    py37_0    defaults
soupsieve                 1.8                      py37_0    defaults
sphinx                    2.0.1                      py_0    defaults
sphinxcontrib-applehelp   1.0.1                      py_0    defaults
sphinxcontrib-devhelp     1.0.1                      py_0    defaults
sphinxcontrib-htmlhelp    1.0.2                      py_0    defaults
sphinxcontrib-jsmath      1.0.1                      py_0    defaults
sphinxcontrib-qthelp      1.0.2                      py_0    defaults
sphinxcontrib-serializinghtml 1.1.3                      py_0    defaults
spyder                    4.0.0b2                  py37_0    spyder-ide
spyder-kernels            1.3.2                    py37_0    defaults
sqlite                    3.27.2               h7b6447c_0    defaults
termcolor                 1.1.0                    py37_1    defaults
terminado                 0.8.1                    py37_1    defaults
testpath                  0.3.1                    py37_0    defaults
tk                        8.6.8                         0    conda-forge
toml                      0.10.0           py37h28b3542_0    defaults
tornado                   5.1              py37h470a237_1    conda-forge
tox                       3.11.1                     py_0    conda-forge
tox-conda                 0.2.0                      py_0    conda-forge
tqdm                      4.31.1                   py37_1    defaults
traitlets                 4.3.2                    py37_0    defaults
twisted                   18.7.0           py37h14c3975_1    defaults
urllib3                   1.23                     pypi_0    pypi
virtualenv                16.0.0                   py37_0    defaults
wcwidth                   0.1.7                      py_1    conda-forge
webencodings              0.5.1                    py37_1    defaults
wheel                     0.31.1                   py37_1    conda-forge
whichcraft                0.5.2                      py_1    conda-forge
widgetsnbextension        3.4.2                    py37_0    defaults
wrapt                     1.11.1           py37h7b6447c_0    defaults
wurlitzer                 1.0.2                    py37_0    defaults
wxpython                  4.0.4            py37h812d2d3_0    conda-forge
xorg-kbproto              1.0.7             h14c3975_1002    conda-forge
xorg-libice               1.0.9             h516909a_1004    conda-forge
xorg-libsm                1.2.3             h84519dc_1000    conda-forge
xorg-libx11               1.6.7             h14c3975_1000    conda-forge
xorg-libxau               1.0.8                h470a237_6    conda-forge
xorg-libxdmcp             1.1.2                h470a237_7    conda-forge
xorg-libxext              1.3.4                h516909a_0    conda-forge
xorg-libxrender           0.9.10            h516909a_1002    conda-forge
xorg-renderproto          0.11.1            h14c3975_1002    conda-forge
xorg-xextproto            7.3.0             h14c3975_1002    conda-forge
xorg-xproto               7.0.31            h14c3975_1007    conda-forge
xz                        5.2.4                h470a237_1    conda-forge
yaml                      0.1.7                h470a237_1    conda-forge
yapf                      0.27.0                     py_0    defaults
ypkpathway                1.0.1                     dev_0    <develop>
zeromq                    4.2.5                hfc679d8_5    conda-forge
zlib                      1.2.11               h470a237_3    conda-forge
zope                      1.0                      py37_0    defaults
zope.interface            4.5.0            py37h14c3975_0    defaults
(bjorn37) bjorn@Tp:~/Desktop$ 
</details>







Discussion:
Thanks for reporting, I noticed this too. It's a regression from our refactoring of editor and console calltips.

@dalthviz, please take a look at this one. The idea is to try to detect the object's signature and also display a bit of its docstring (which is very similar to the way things are working on the editor).
Thanks for the attention and for editing the title!

Resolving patch:
diff --git a/spyder/plugins/ipythonconsole/widgets/help.py b/spyder/plugins/ipythonconsole/widgets/help.py
--- a/spyder/plugins/ipythonconsole/widgets/help.py
+++ b/spyder/plugins/ipythonconsole/widgets/help.py
@@ -37,6 +37,16 @@ def clean_invalid_var_chars(self, var):
         """
         return re.sub(r'\W|^(?=\d)', '_', var)
 
+    def get_documentation(self, content):
+        """Get documentation fron inspect reply content."""
+        data = content.get('data', {})
+        text = data.get('text/plain', '')
+        signature = self.get_signature(content).split('(')[-1]
+        if text:
+            documentation = text.split(signature)
+            if len(documentation) > 1:
+                return documentation[-1]
+
     def get_signature(self, content):
         """Get signature from inspect reply content"""
         data = content.get('data', {})
@@ -49,9 +59,10 @@ def get_signature(self, content):
             name = name.split('.')[-1]        # Then take last token after a .
             # Clean name from invalid chars
             try:
-                name = self.clean_invalid_var_chars(name).split('_')[-1]
+                name = self.clean_invalid_var_chars(name)
             except:
                 pass
+            text = text.split('Docstring:')[-1]
             argspec = getargspecfromtext(text)
             if argspec:
                 # This covers cases like np.abs, whose docstring is
@@ -60,7 +71,6 @@ def get_signature(self, content):
                 signature = name + argspec
             else:
                 signature = getsignaturefromtext(text, name)
-
             # Remove docstring for uniformity with editor
             signature = signature.split('Docstring:')[0]
 
@@ -123,13 +133,16 @@ def _handle_inspect_reply(self, rep):
         """
         cursor = self._get_cursor()
         info = self._request_info.get('call_tip')
-        if info and info.id == rep['parent_header']['msg_id'] and \
-          info.pos == cursor.position():
+        if (info and info.id == rep['parent_header']['msg_id'] and
+                info.pos == cursor.position()):
             content = rep['content']
             if content.get('status') == 'ok' and content.get('found', False):
                 signature = self.get_signature(content)
+                documentation = self.get_documentation(content)
                 if signature:
                     self._control.show_calltip(
                         signature,
-                        language=self.language_name
+                        documentation=documentation,
+                        language=self.language_name,
+                        max_lines=5
                     )
diff --git a/spyder/widgets/mixins.py b/spyder/widgets/mixins.py
--- a/spyder/widgets/mixins.py
+++ b/spyder/widgets/mixins.py
@@ -428,7 +428,7 @@ def _check_signature_and_format(self, signature_or_text, parameter=None,
         return new_signature, extra_text, inspect_word
 
     def show_calltip(self, signature, parameter=None, documentation=None,
-                     language=_DEFAULT_LANGUAGE):
+                     language=_DEFAULT_LANGUAGE, max_lines=10):
         """
         Show calltip.
 
@@ -465,7 +465,7 @@ def show_calltip(self, signature, parameter=None, documentation=None,
             inspect_word=inspect_word,
             display_link=False,
             text=documentation,
-            max_lines=10,
+            max_lines=max_lines,
         )
 
         self._update_stylesheet(self.calltip_widget)


Test patch:
diff --git a/spyder/plugins/ipythonconsole/tests/test_ipythonconsole.py b/spyder/plugins/ipythonconsole/tests/test_ipythonconsole.py
--- a/spyder/plugins/ipythonconsole/tests/test_ipythonconsole.py
+++ b/spyder/plugins/ipythonconsole/tests/test_ipythonconsole.py
@@ -153,23 +153,27 @@ def close_console():
 @flaky(max_runs=3)
 @pytest.mark.skipif(sys.platform == 'darwin', reason="Times out on macOS")
 def test_get_calltips(ipyconsole, qtbot):
-    """Test that calltips work."""
+    """Test that calltips show the documentation."""
     shell = ipyconsole.get_current_shellwidget()
     control = shell._control
     qtbot.waitUntil(lambda: shell._prompt_html is not None,
                     timeout=SHELL_TIMEOUT)
 
+    # Import numpy
+    with qtbot.waitSignal(shell.executed):
+        shell.execute('import numpy as np')
+
     # Write an object in the console that should generate a calltip
     # and wait for the kernel to send its response.
     with qtbot.waitSignal(shell.kernel_client.shell_channel.message_received):
-        qtbot.keyClicks(control, 'range(')
+        qtbot.keyClicks(control, 'np.abs(')
 
     # Wait a little bit for the calltip to appear
     qtbot.wait(500)
 
     # Assert we displayed a calltip
     assert control.calltip_widget.isVisible()
-
+    assert 'Calculate the absolute value' in control.calltip_widget.text()
     # Hide the calltip to avoid focus problems on Linux
     control.calltip_widget.hide()