Repository: spyder-ide/spyder

Issue:
Unusual characters break help
<!--- **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
* [ ] 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)
* [ ] Could not reproduce inside ``jupyter qtconsole`` (if console-related)
* [ ] Tried basic troubleshooting (if a bug/error)
    * [ ] Restarted Spyder
    * [ ] 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

[Weird but valid characters in function names](https://www.dcl.hpi.uni-potsdam.de/home/loewis/table-3131.html) are not recognized by Spyder so it doesn't show the docstring.

### What steps reproduce the problem?

1. Create a function with name `aaʹbb`
2. Type aa and press Tab to complete the name
3. Press Ctrl+I for help on that function.  

### What is the expected output? 

Help says "No documentation available" for object `bb`.


### What do you see instead?

It should show documentation for object `aaʹbb`



### Paste Traceback/Error Below (if applicable)
<!--- Copy from error dialog or View > Panes > Internal Console --->

```python-traceback

def aaʹbb(a):
    """this is the docstring"""
    pass


aaʹbb
Out[3]: <function __main__.aaʹbb>

aaʹbb?
Signature: aaʹbb(a)
Docstring: this is the docstring
```


## Versions
<!--- You can get this information from Help > About Spyder...
or (if Spyder won't launch) the "conda list" command
from the Anaconda Prompt/Terminal/command line. --->

* Spyder version: 3.3.1
* Python version: 3.6.4
* Qt version: 5.6.2
* PyQt version: 5.6
* Operating System name/version: Windows 7 

### Dependencies
<!--- Please go to the menu entry Help > Dependencies,
press the Copy to clipboard button and paste below --->

```
IPython >=4.0     :  6.2.1 (OK)
cython >=0.21     :  0.27.3 (OK)
jedi >=0.9.0      :  0.11.1 (OK)
matplotlib >=2.0.0:  2.2.3 (OK)
nbconvert >=4.0   :  5.3.1 (OK)
numpy >=1.7       :  1.14.3 (OK)
pandas >=0.13.1   :  0.22.0 (OK)
pycodestyle >=2.3 :  2.3.1 (OK)
pyflakes >=0.6.0  :  1.6.0 (OK)
pygments >=2.0    :  2.2.0 (OK)
pylint >=0.25     :  1.8.2 (OK)
qtconsole >=4.2.0 :  4.3.1 (OK)
rope >=0.9.4      :  0.10.7 (OK)
sphinx >=0.6.6    :  1.6.6 (OK)
sympy >=0.7.3     :  1.1.1 (OK)

```



Discussion:
Thanks for reporting. We'll take a look at this in Spyder 4.
This is still an issue o Spyder 4.0

Resolving patch:
diff --git a/spyder/widgets/mixins.py b/spyder/widgets/mixins.py
--- a/spyder/widgets/mixins.py
+++ b/spyder/widgets/mixins.py
@@ -1330,15 +1330,7 @@ def set_help_enabled(self, state):
         self.help_enabled = state
 
     def inspect_current_object(self):
-        text = ''
-        text1 = self.get_text('sol', 'cursor')
-        tl1 = re.findall(r'([a-zA-Z_]+[0-9a-zA-Z_\.]*)', text1)
-        if tl1 and text1.endswith(tl1[-1]):
-            text += tl1[-1]
-        text2 = self.get_text('cursor', 'eol')
-        tl2 = re.findall(r'([0-9a-zA-Z_\.]+[0-9a-zA-Z_\.]*)', text2)
-        if tl2 and text2.startswith(tl2[0]):
-            text += tl2[0]
+        text = self.get_current_word(help_req=True)
         if text:
             self.show_object_info(text, force=True)
 


Test patch:
diff --git a/spyder/app/tests/script_unicode.py b/spyder/app/tests/script_unicode.py
new file mode 100644
--- /dev/null
+++ b/spyder/app/tests/script_unicode.py
@@ -0,0 +1,3 @@
+def aaʹbb(a):
+    """This function docstring."""
+    return True
diff --git a/spyder/app/tests/test_mainwindow.py b/spyder/app/tests/test_mainwindow.py
--- a/spyder/app/tests/test_mainwindow.py
+++ b/spyder/app/tests/test_mainwindow.py
@@ -430,6 +430,49 @@ def test_get_help_combo(main_window, qtbot):
     qtbot.waitUntil(lambda: check_text(webpage, "arange"), timeout=6000)
 
 
+@pytest.mark.slow
+@pytest.mark.skipif(PY2, reason="Invalid definition of function in Python 2.")
+def test_get_help_ipython_console_special_characters(
+        main_window, qtbot, tmpdir):
+    """
+    Test that Help works when called from the IPython console
+    for unusual characters.
+
+    See spyder-ide/spyder#7699
+    """
+    shell = main_window.ipyconsole.get_current_shellwidget()
+    control = shell._control
+    qtbot.waitUntil(lambda: shell._prompt_html is not None,
+                    timeout=SHELL_TIMEOUT)
+
+    # Open test file
+    test_file = osp.join(LOCATION, 'script_unicode.py')
+    main_window.editor.load(test_file)
+    code_editor = main_window.editor.get_focus_widget()
+
+    # Run test file
+    qtbot.keyClick(code_editor, Qt.Key_F5)
+    qtbot.wait(500)
+
+    help_plugin = main_window.help
+    webview = help_plugin.rich_text.webview._webview
+    webpage = webview.page() if WEBENGINE else webview.page().mainFrame()
+
+    # Write function name and assert in Console
+    def check_control(control, value):
+       return value in control.toPlainText()
+
+    qtbot.keyClicks(control, u'aa\t')
+    qtbot.waitUntil(lambda: check_control(control, u'aaʹbb'), timeout=2000)
+
+    # Get help
+    control.inspect_current_object()
+
+    # Check that a expected text is part of the page
+    qtbot.waitUntil(lambda: check_text(webpage, "This function docstring."),
+                    timeout=6000)
+
+
 @pytest.mark.slow
 @flaky(max_runs=3)
 @pytest.mark.skipif(os.name == 'nt' and os.environ.get('CI') is not None,