Repository: spyder-ide/spyder

Issue:
TypeError: KiteClient.sig_response_ready in Kite's client
## Description

### What steps will reproduce the problem?

<!--- You can use Markdown here --->

I the procedures on the uninstall of kite through the terminal. Then I found the kite folders on my macbook and i send them to trash, but now my spider give me this issue report constantly. 

i tryed to open a new enviroment in anaconda but the problem persist.

Should I unistall and reinstall all spider?

Thx



### Traceback
```python-traceback
  File "/Users/xaf/opt/anaconda3/lib/python3.7/site-packages/spyder/plugins/completion/kite/client.py", line 173, in perform_request
    self.sig_response_ready.emit(req_id, response or {})
TypeError: KiteClient.sig_response_ready[int, dict].emit(): argument 2 has unexpected type 'str'
Traceback (most recent call last):
  File "/Users/xaf/opt/anaconda3/lib/python3.7/site-packages/spyder/plugins/completion/kite/client.py", line 173, in perform_request
    self.sig_response_ready.emit(req_id, response or {})
TypeError: KiteClient.sig_response_ready[int, dict].emit(): argument 2 has unexpected type 'str'
```

## Versions

* Spyder version: 4.1.3 
* Python version: 3.7.6
* Qt version: 5.9.6
* PyQt5 version: 5.9.2
* Operating System: Darwin 19.3.0

### Dependencies

```

# Mandatory:
applaunchservices >=0.1.7      :  0.2.1 (OK)
atomicwrites >=1.2.0           :  1.4.0 (OK)
chardet >=2.0.0                :  3.0.4 (OK)
cloudpickle >=0.5.0            :  1.4.1 (OK)
diff_match_patch >=20181111    :  20181111 (OK)
intervaltree                   :  None (OK)
IPython >=4.0                  :  7.13.0 (OK)
jedi =0.15.2                   :  0.15.2 (OK)
nbconvert >=4.0                :  5.6.1 (OK)
numpydoc >=0.6.0               :  1.0.0 (OK)
parso =0.5.2                   :  0.5.2 (OK)
pexpect >=4.4.0                :  4.8.0 (OK)
pickleshare >=0.4              :  0.7.5 (OK)
psutil >=5.3                   :  5.7.0 (OK)
pygments >=2.0                 :  2.6.1 (OK)
pylint >=0.25                  :  2.4.4 (OK)
pyls >=0.31.9;<0.32.0          :  0.31.10 (OK)
qdarkstyle >=2.8               :  2.8.1 (OK)
qtawesome >=0.5.7              :  0.7.2 (OK)
qtconsole >=4.6.0              :  4.7.4 (OK)
qtpy >=1.5.0                   :  1.9.0 (OK)
rtree >=0.8.3                  :  0.9.4 (OK)
sphinx >=0.6.6                 :  3.0.4 (OK)
spyder_kernels >=1.9.1;<1.10.0 :  1.9.1 (OK)
watchdog                       :  None (OK)
zmq >=17                       :  18.1.1 (OK)

# Optional:
cython >=0.21                  :  0.29.20 (OK)
matplotlib >=2.0.0             :  3.1.3 (OK)
numpy >=1.7                    :  1.18.1 (OK)
pandas >=0.13.1                :  1.0.4 (OK)
scipy >=0.17.0                 :  1.4.1 (OK)
sympy >=0.7.3                  :  1.5.1 (OK)
```



Discussion:
@xavierricci, thanks for reporting. We're not really sure what to do about your problem.

@dalthviz, is there anything we could to prevent this?
I will need to check @ccordoba12.

Maybe for now @xavierricci , as a workaround, you could try to disable Kite from the preferences of Spyder? (if Spyder doesn't start check for the `spyder.ini` file which should be in `...\.spyder-py3\config` under your user, and change there the option `enable` under the `[kite]` section)
Note: After a quick check of the code, a validation could be added before emitting the signal as well as a message indicating that an unexpected result from Kite was received and you need to check your Kite installation (maybe we can add a link in that message to the Kite troubleshooting page or their link to contact support?).
Agreed, those are very good ideas @dalthviz!

Resolving patch:
diff --git a/spyder/plugins/completion/kite/client.py b/spyder/plugins/completion/kite/client.py
--- a/spyder/plugins/completion/kite/client.py
+++ b/spyder/plugins/completion/kite/client.py
@@ -15,10 +15,12 @@
 
 # Third party imports
 from qtpy.QtCore import QObject, QThread, Signal, QMutex
+from qtpy.QtWidgets import QMessageBox
 import requests
 
 # Local imports
-from spyder.config.base import _
+from spyder.config.base import _, running_under_pytest
+from spyder.config.manager import CONF
 from spyder.plugins.completion.kite import KITE_ENDPOINTS, KITE_REQUEST_MAPPING
 from spyder.plugins.completion.kite.decorators import class_register
 from spyder.plugins.completion.kite.providers import KiteMethodProviderMixIn
@@ -41,6 +43,7 @@ class KiteClient(QObject, KiteMethodProviderMixIn):
     sig_status_response_ready = Signal((str,), (dict,))
     sig_perform_onboarding_request = Signal()
     sig_onboarding_response_ready = Signal(str)
+    sig_client_wrong_response = Signal(str, object)
 
     def __init__(self, parent, enable_code_snippets=True):
         QObject.__init__(self, parent)
@@ -170,4 +173,8 @@ def perform_request(self, req_id, method, params):
                 converter = getattr(self, converter_name)
                 if response is not None:
                     response = converter(response)
-        self.sig_response_ready.emit(req_id, response or {})
+        if not isinstance(response, (dict, type(None))):
+            if not running_under_pytest():
+                self.sig_client_wrong_response.emit(method, response)
+        else:
+            self.sig_response_ready.emit(req_id, response or {})
diff --git a/spyder/plugins/completion/kite/plugin.py b/spyder/plugins/completion/kite/plugin.py
--- a/spyder/plugins/completion/kite/plugin.py
+++ b/spyder/plugins/completion/kite/plugin.py
@@ -70,6 +70,8 @@ def __init__(self, parent):
         self.client.sig_status_response_ready.connect(self._kite_onboarding)
         self.client.sig_onboarding_response_ready.connect(
             self._show_onboarding_file)
+        self.client.sig_client_wrong_response.connect(
+            self._wrong_response_error)
 
         self.installation_thread.sig_installation_status.connect(
             self.set_status)
@@ -222,3 +224,16 @@ def _show_onboarding_file(self, onboarding_file):
             return
         self.set_option('show_onboarding', False)
         self.main.open_file(onboarding_file)
+
+    @Slot(str, object)
+    def _wrong_response_error(self, method, resp):
+        QMessageBox.critical(
+            self.main, _('Kite error'),
+            _("The Kite completion engine returned an unexpected result "
+              "for the request <tt>{0}</tt>: <br><br><tt>{1}</tt><br><br>"
+              "Please make sure that your Kite installation is correct. "
+              "In the meantime, Spyder will disable the Kite client to "
+              "prevent further errors. For more information, please "
+              "visit the <a href='https://help.kite.com/'>Kite help "
+              "center</a>").format(method, resp))
+        self.set_option('enable', False)


Test patch: