Repository: spyder-ide/spyder
Pull request: PR: Fix wrapping calltip text for elements without signature in the IPython console
<!--- Make sure to read the Contributing Guidelines:                   --->
<!--- https://github.com/spyder-ide/spyder/blob/master/CONTRIBUTING.md --->
<!--- and follow PEP 8, PEP 257 and Spyder's code style:               --->
<!--- https://github.com/spyder-ide/spyder/wiki/Dev:-Coding-Style      --->

## Description of Changes


* [ ] Wrote at least one-line docstrings (for any new functions)
* [ ] Added unit test(s) covering the changes (if testable)
<!--- Remember that an image/animation is worth a thousand words! --->
* [x] Included a screenshot or animation (if affecting the UI, see [Licecap](https://www.cockos.com/licecap/))


<!--- Explain what you've done and why --->

#### Before:
![image](https://user-images.githubusercontent.com/16781833/62173327-4115e480-b2fb-11e9-8fad-8100dedc2def.png)


#### After:
![Untitled](https://user-images.githubusercontent.com/16781833/62254027-53585700-b3bd-11e9-8545-69ef440e669f.png)


### Issue(s) Resolved

<!--- List the issue(s) below, in the form "Fixes #1234"; one per line --->

Fixes #9911 


### Affirmation

By submitting this Pull Request or typing my (user)name below,
I affirm the [Developer Certificate of Origin](https://developercertificate.org)
with respect to all commits and content included in this PR,
and understand I am releasing the same under Spyder's MIT (Expat) license.

<!--- TYPE YOUR USER/NAME AFTER THE FOLLOWING: --->
I certify the above statement is true and correct: dalthviz

<!--- Thanks for your help making Spyder better for everyone! --->


Problem statement:
IPython console crashes when using netCDF4
## Problem Description
Spyder 4.0.0b3 crashes when loading and using netCDF4 package within the iPython Console. Does not happen with the editor.


### What steps reproduce the problem?
1. import netcdf4
2. Only in the iPython console -> when typing "netcdf4.Dataset( " the exact same moment as you type the first bracket the IDE crashes and the ubuntu crashes with it.


### What is the expected output? What do you see instead?
Instead of opening the function description window the whole thing crashes and takes the ubuntu OS with it.

--- Note ---
I'm running spyder4.0.0b3 via x11 forwarding from our dept. server. Previous versions of Spyder always worked perfectly and smoothly with zero errors.

My local machine runs Ubuntu 18.04.2 LTS
The server's machine is 	CentOS Linux release 7.4.1708


## Versions
* Spyder version: Spyder 4.0.0b3 
* Python version: Python 3.7.3 64-bit
* Qt version: Qt 5.9.7 
* PyQt version: PyQt5 5.9.2 
* Operating System nQt 5.9.7 ame/version: Linux 3.10.0-693.5.2.el7.x86_64 


### Dependencies
```
pygments >=2.0    :  2.4.2 (OK)
qdarkstyle >=2.6.4:  2.7 (OK)
sphinx >=0.6.6    :  2.1.0 (OK)
psutil >=0.3      :  5.6.2 (OK)
pyls >=0.27.0     :  0.27.0 (OK)
nbconvert >=4.0   :  5.5.0 (OK)
pandas >=0.13.1   :  0.24.2 (OK)
numpy >=1.7       :  1.16.4 (OK)
sympy >=0.7.3     :  1.4 (OK)
cython >=0.21     :  0.29.13 (OK)
qtconsole >=4.5.0 :  4.5.1 (OK)
IPython >=4.0     :  7.5.0 (OK)
matplotlib >=2.0.0:  3.1.0 (OK)
pylint >=0.25     :  2.3.1 (OK)
```

Hints from issue discussion:
Thanks for reporting. How did you install Spyder and netcdf4?
Thanks for the quick reply!
I installed Spyder as such;
conda update qt pyqt
conda install -c spyder-ide spyder=4.0.0b3
(as instructed here - https://github.com/spyder-ide/spyder/releases/tag/v4.0.0b3)


and as for the netCDF4

conda install netcdf4


Stav
We're you able to reproduce the error?
We'll take a look at it for beta5 because beta4 (to be released this week) is almost ready.
@dalthviz, please take a look at this one to see if you can reproduce it.
Cheers, I'll keep following the thread and if anything comes up I'll keep u updated
thanks for the hard work!


I think the problem here was the calltip being to wide (do the wrapping not working correctly). @stavna could you try to check if the changes made in PR #9925 fix the issue? Thanks :)

Commit message: Mixins - Ipython Console: Fix calltip handling of paragraphs. Fix tests

Patch to review:
diff --git a/spyder/plugins/ipythonconsole/tests/test_ipythonconsole.py b/spyder/plugins/ipythonconsole/tests/test_ipythonconsole.py
index b7d3fbc66b3..ccec60d20de 100644
--- a/spyder/plugins/ipythonconsole/tests/test_ipythonconsole.py
+++ b/spyder/plugins/ipythonconsole/tests/test_ipythonconsole.py
@@ -173,11 +173,11 @@ def close_console():
         [("arange",
           ["start", "stop"],
           ["Return evenly spaced values within a given interval.<br>",
-           "returns an ndarray rather than a list.<br>"]),
+           "<br>Python built-in`range` function, but returns an ndarray ..."]),
          ("vectorize",
           ["pyfunc", "otype", "signature"],
           ["Generalized function class.<br>",
-           "numpy array or a tuple of numpy ..."]),
+           "Define a vectorized function which takes a nested sequence ..."]),
          ("absolute",
           ["x", "/", "out"],
           ["Parameters<br>", "x : array_like ..."])]
diff --git a/spyder/widgets/mixins.py b/spyder/widgets/mixins.py
index ead31294f76..87b506954d2 100644
--- a/spyder/widgets/mixins.py
+++ b/spyder/widgets/mixins.py
@@ -205,19 +205,32 @@ def _format_text(self, title=None, signature=None, text=None,
             text = text.strip()
 
         if not with_html_format:
-            paragraphs = text.splitlines()
+            # All the replacement are need to properly divide the
+            # text in actual paragraphs and wrap the text on each one
+            paragraphs = (text.replace("\n\n", "<!DOUBLE_ENTER!>")
+                          .replace(".\n", ".<!SINGLE_ENTER!>")
+                          .replace("\n-", "<!SINGLE_ENTER!>-")
+                          .replace("-\n", "-<!SINGLE_ENTER!>")
+                          .replace("\n ", "<!SINGLE_ENTER!> ")
+                          .replace("\n", "")
+                          .replace("<!DOUBLE_ENTER!>", "\n\n")
+                          .replace("<!SINGLE_ENTER!>", "\n").splitlines())
+            new_paragraphs = []
             for paragraph in paragraphs:
                 # Wrap text
-                paragraph = textwrap.wrap(text, width=max_width)
+                new_paragraph = textwrap.wrap(paragraph, width=max_width)
 
                 # Remove empty lines at the beginning
-                paragraph = [l for l in paragraph if l.strip()]
+                new_paragraph = [l for l in new_paragraph if l.strip()]
 
                 # Merge paragraph text
-                paragraph = '\n'.join(paragraph)
+                new_paragraph = '\n'.join(new_paragraph)
+
+                # Add new paragraph
+                new_paragraphs.append(new_paragraph)
 
             # Join paragraphs and split in lines for max_lines check
-            paragraphs = '\n'.join(paragraphs)
+            paragraphs = '\n'.join(new_paragraphs)
             paragraphs = paragraphs.strip('\r\n')
             lines = paragraphs.splitlines()
 


Code review comments:
diff_hunk: @@ -205,19 +205,32 @@ def _format_text(self, title=None, signature=None, text=None,
             text = text.strip()
 
         if not with_html_format:
-            paragraphs = text.splitlines()
+            # All the replacement are need to properly divide the
path: spyder/widgets/mixins.py
text: @user1:
Let's change this to

    # All these replacements are ...