Repository: spyder-ide/spyder

Issue:
Another TypeError when going to definition
## Description

### What steps will reproduce the problem?

<!--- You can use Markdown here --->

Try to go to definition of any 3rd party package
Maybe I set incorrect path using PYTHONPATH Manager?
I've set path ".../venv/lib64/python3.7/site-packages". Is it correct?
So, system libraries definition opens fine

### Traceback
```python-traceback
  File "/home/kai/Projects/spyder/4/lib/python3.7/site-packages/spyder/plugins/editor/widgets/codeeditor.py", line 1221, in handle_go_to_definition
    def_range = position['range']
TypeError: string indices must be integers
```

## Versions

* Spyder version: 4.0.0b7 
* Python version: 3.7.3
* Qt version: 5.12.4
* PyQt5 version: 5.12.3
* Operating System: Linux 4.19.0-6-amd64

### Dependencies

```
cloudpickle >=0.5.0          :  1.2.2 (OK)
pygments >=2.0               :  2.4.2 (OK)
qtconsole >=4.5.5            :  4.5.5 (OK)
nbconvert >=4.0              :  5.6.0 (OK)
sphinx >=0.6.6               :  2.2.0 (OK)
pylint >=0.25                :  2.4.2 (OK)
psutil >=0.3                 :  5.6.3 (OK)
qtawesome >=0.5.7            :  0.6.0 (OK)
qtpy >=1.5.0                 :  1.9.0 (OK)
pickleshare >=0.4            :  0.7.5 (OK)
zmq >=17                     :  18.1.0 (OK)
chardet >=2.0.0              :  3.0.4 (OK)
numpydoc >=0.6.0             :  0.9.1 (OK)
spyder_kernels >=1.5.0;<2.0.0:  1.6.0 (OK)
qdarkstyle >=2.7             :  2.7 (OK)
atomicwrites >=1.2.0         :  1.3.0 (OK)
diff_match_patch >=20181111  :  20181111 (OK)
watchdog                     :  None (OK)
keyring                      :  None (OK)
pexpect >=4.4.0              :  4.7.0 (OK)
pympler                      :  None (OK)
sympy >=0.7.3                :  None (NOK)
cython >=0.21                :  None (NOK)
IPython >=4.0                :  7.8.0 (OK)
matplotlib >=2.0.0           :  None (NOK)
pandas >=0.13.1              :  None (NOK)
numpy >=1.7                  :  None (NOK)
scipy >=0.17.0               :  None (NOK)
pyls >=0.28.2;<0.29.0        :  0.28.3 (OK)
xdg >=0.26                   :  0.26 (OK)
```



Discussion:
> I've set path ".../venv/lib64/python3.7/site-packages". Is it correct?

No, it's not. Please remove that directory from our PYTHONPATH manager and install Spyder in your virtualenv instead.
This error was fixed in beta7 (although you said you're using that version). So please provide an example that's giving you this error (after removing `.../venv/lib64/python3.7/site-packages` from our PYTHONPATH manager).
Great thank, i've change entry in PYTHONPATH Manager, but i don't see any changes: the same exception
Please post a simple code example that is generating this problem.
Yes, I have:
```
def should_use_eventloop(self):
    return True


def patch_worker():
    from celery.worker import worker
    WorkController = worker.WorkController
    WorkController.should_use_eventloop = should_use_eventloop
```
It's here: https://github.com/kai3341/celery-pool-asyncio/pull/6/files#diff-5e7af6bd673f217e167fb73924ff71e9
I'm trying to go to definition of worker
@steff456, please try to reproduce this one on Linux.
A simpler code to generate this error:

```python
from qtpy.QtCore import Qt
Qt.FramelessWindowHint
```

and trying to go to the definition of `FramelessWindowHint`.

Resolving patch:
diff --git a/spyder/plugins/completion/plugin.py b/spyder/plugins/completion/plugin.py
--- a/spyder/plugins/completion/plugin.py
+++ b/spyder/plugins/completion/plugin.py
@@ -20,7 +20,7 @@
 from qtpy.QtWidgets import QMessageBox
 
 # Local imports
-from spyder.config.base import _, get_conf_path, running_under_pytest
+from spyder.config.base import _, get_conf_path
 from spyder.config.lsp import PYTHON_CONFIG
 from spyder.api.completion import SpyderCompletionPlugin
 from spyder.utils.misc import select_port, getcwd_or_home
@@ -166,10 +166,10 @@ def gather_completions(self, req_id_responses):
         return responses
 
     def gather_default(self, req_type, responses):
-        response = ''
+        response = None
         for source in self.SOURCE_PRIORITY[req_type]:
             if source in responses:
-                response = responses[source].get('params', '')
+                response = responses[source].get('params', None)
                 if response:
                     break
         return {'params': response}
diff --git a/spyder/plugins/editor/widgets/codeeditor.py b/spyder/plugins/editor/widgets/codeeditor.py
--- a/spyder/plugins/editor/widgets/codeeditor.py
+++ b/spyder/plugins/editor/widgets/codeeditor.py
@@ -1171,7 +1171,7 @@ def handle_hover_response(self, contents):
             content = contents['params']
             self.sig_display_object_info.emit(content,
                                               self._request_hover_clicked)
-            if self._show_hint and self._last_point and content:
+            if content is not None and self._show_hint and self._last_point:
                 # This is located in spyder/widgets/mixins.py
                 word = self._last_hover_word,
                 content = content.replace(u'\xa0', ' ')


Test patch:
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
@@ -13,13 +13,14 @@
 # Standard library imports
 import os
 import os.path as osp
+import re
 import shutil
 import tempfile
+from textwrap import dedent
 try:
     from unittest.mock import Mock, MagicMock
 except ImportError:
     from mock import Mock, MagicMock  # Python 2
-import re
 import sys
 import uuid
 
@@ -2131,6 +2132,52 @@ def trigger():
     qtbot.wait(5000)
 
 
+@pytest.mark.slow
+@flaky(max_runs=3)
+@pytest.mark.use_introspection
+@pytest.mark.skipif(os.name == 'nt', reason="It times out on Windows")
+def test_go_to_definition(main_window, qtbot, capsys):
+    """Test that go-to-definition works as expected."""
+    # --- Code that gives no definition
+    code_no_def = dedent("""
+    from qtpy.QtCore import Qt
+    Qt.FramelessWindowHint""")
+
+    # Create new editor with code and wait until LSP is ready
+    main_window.editor.new(text=code_no_def)
+    code_editor = main_window.editor.get_focus_widget()
+    with qtbot.waitSignal(code_editor.lsp_response_signal, timeout=30000):
+        code_editor.document_did_open()
+
+    # Move cursor to the left one character to be next to
+    # FramelessWindowHint
+    code_editor.move_cursor(-1)
+    with qtbot.waitSignal(code_editor.lsp_response_signal):
+        code_editor.go_to_definition_from_cursor()
+
+    # Capture stderr and assert there are no errors
+    sys_stream = capsys.readouterr()
+    assert sys_stream.err == u''
+
+    # --- Code that gives definition
+    code_def = "import qtpy.QtCore"
+
+    # Create new editor with code and wait until LSP is ready
+    main_window.editor.new(text=code_def)
+    n_editors = len(main_window.editor.get_filenames())
+    code_editor = main_window.editor.get_focus_widget()
+    with qtbot.waitSignal(code_editor.lsp_response_signal, timeout=30000):
+        code_editor.document_did_open()
+
+    # Move cursor to the left one character to be next to QtCore
+    code_editor.move_cursor(-1)
+    with qtbot.waitSignal(code_editor.lsp_response_signal):
+        code_editor.go_to_definition_from_cursor()
+
+    # Assert there's one more file open than before
+    assert len(main_window.editor.get_filenames()) == n_editors + 1
+
+
 @pytest.mark.slow
 @flaky(max_runs=3)
 def test_debug_unsaved_file(main_window, qtbot):
diff --git a/spyder/plugins/editor/widgets/tests/test_codeeditor.py b/spyder/plugins/editor/widgets/tests/test_codeeditor.py
--- a/spyder/plugins/editor/widgets/tests/test_codeeditor.py
+++ b/spyder/plugins/editor/widgets/tests/test_codeeditor.py
@@ -143,8 +143,8 @@ def test_editor_log_lsp_handle_errors(editorbot, capsys):
          [Qt.Key_Enter],
          True),
     ])
-def test_editor_rstrip_keypress(
-        editorbot, input_text, expected_text, keys, strip_all):
+def test_editor_rstrip_keypress(editorbot, input_text, expected_text, keys,
+                                strip_all):
     """
     Test that whitespace is removed when leaving a line.
     """