Repository: spyder-ide/spyder

Issue:
CommError: The comm is not connected when changing Matplotlib backend
## Description

### What steps will reproduce the problem?

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

when choosing inline backend graphics, the spyder returns an error message

### Traceback
```python-traceback
Traceback (most recent call last):
  File "C:\Users\wisam\anaconda3\envs\PEA Tabular Project\lib\site-packages\spyder\plugins\preferences\widgets\configdialog.py", line 127, in accept
    configpage.apply_changes()
  File "C:\Users\wisam\anaconda3\envs\PEA Tabular Project\lib\site-packages\spyder\plugins\preferences\api.py", line 110, in apply_changes
    self.apply_callback()
  File "C:\Users\wisam\anaconda3\envs\PEA Tabular Project\lib\site-packages\spyder\plugins\preferences\api.py", line 142, in <lambda>
    self._apply_settings_tabs(self.changed_options))
  File "C:\Users\wisam\anaconda3\envs\PEA Tabular Project\lib\site-packages\spyder\plugins\preferences\api.py", line 170, in _apply_settings_tabs
    self.apply_settings(options)
  File "C:\Users\wisam\anaconda3\envs\PEA Tabular Project\lib\site-packages\spyder\api\preferences.py", line 104, in wrapper
    func(opts)
  File "C:\Users\wisam\anaconda3\envs\PEA Tabular Project\lib\site-packages\spyder\plugins\ipythonconsole\plugin.py", line 447, in apply_plugin_settings
    for client in self.clients]
  File "C:\Users\wisam\anaconda3\envs\PEA Tabular Project\lib\site-packages\spyder\plugins\ipythonconsole\plugin.py", line 447, in <listcomp>
    for client in self.clients]
  File "C:\Users\wisam\anaconda3\envs\PEA Tabular Project\lib\site-packages\spyder\plugins\ipythonconsole\widgets\shell.py", line 343, in get_matplotlib_backend
    blocking=True).get_matplotlib_backend()
  File "C:\Users\wisam\anaconda3\envs\PEA Tabular Project\lib\site-packages\spyder_kernels\comms\commbase.py", line 550, in __call__
    raise CommError("The comm is not connected.")
spyder_kernels.comms.commbase.CommError: The comm is not connected.
```

## Versions

* Spyder version: 5.0.0 
* Python version: 3.6.13
* Qt version: 5.9.6
* PyQt5 version: 5.9.2
* Operating System: Windows 10

### Dependencies

```

# Mandatory:
atomicwrites >=1.2.0          :  1.4.0 (OK)
chardet >=2.0.0               :  3.0.4 (OK)
cloudpickle >=0.5.0           :  1.6.0 (OK)
cookiecutter >=1.6.0          :  1.7.2 (OK)
diff_match_patch >=20181111   :  20200713 (OK)
intervaltree >=3.0.2          :  3.1.0 (OK)
IPython >=7.6.0               :  7.16.1 (OK)
jedi =0.17.2                  :  0.17.2 (OK)
jsonschema >=3.2.0            :  3.2.0 (OK)
keyring >=17.0.0              :  22.3.0 (OK)
nbconvert >=4.0               :  6.0.7 (OK)
numpydoc >=0.6.0              :  1.1.0 (OK)
paramiko >=2.4.0              :  2.7.2 (OK)
parso =0.7.0                  :  0.7.0 (OK)
pexpect >=4.4.0               :  4.8.0 (OK)
pickleshare >=0.4             :  0.7.5 (OK)
psutil >=5.3                  :  5.8.0 (OK)
pygments >=2.0                :  2.8.1 (OK)
pylint >=1.0                  :  2.7.4 (OK)
pyls >=0.36.2;<1.0.0          :  0.36.2 (OK)
pyls_black >=0.4.6            :  0.4.6 (OK)
pyls_spyder >=0.3.2           :  0.3.2 (OK)
qdarkstyle =3.0.2             :  3.0.2 (OK)
qstylizer >=0.1.10            :  0.1.10 (OK)
qtawesome >=0.5.7             :  1.0.2 (OK)
qtconsole >=5.0.3             :  5.0.3 (OK)
qtpy >=1.5.0                  :  1.9.0 (OK)
rtree >=0.8.3                 :  0.9.4 (OK)
setuptools >=39.0.0           :  52.0.0.post20210125 (OK)
sphinx >=0.6.6                :  3.5.3 (OK)
spyder_kernels >=2.0.1,<2.1.0 :  2.0.1 (NOK)
textdistance >=4.2.0          :  4.2.1 (OK)
three_merge >=0.1.1           :  0.1.1 (OK)
watchdog >=0.10.3;<2.0.0      :  1.0.2 (OK)
zmq >=17                      :  20.0.0 (OK)

# Optional:
cython >=0.21                 :  None (NOK)
matplotlib >=2.0.0            :  3.3.4 (OK)
numpy >=1.7                   :  1.19.5 (OK)
pandas >=1.1.1                :  1.1.5 (OK)
scipy >=0.17.0                :  1.5.2 (OK)
sympy >=0.7.3                 :  None (NOK)
```



Discussion:
Hi @WisamAbbasi,

This is probably an issue with your firewall and/or antivirus. Please try to deactivate them and try again. Also if you want you can try to upgrade to the latest version, 5.0.4 and check if the error persists as well.
I tried to deactivate them, but not working either and I am using the spyder v5
Are you using the latest release 5.0.4 or 5.0.0?
It is 5.0.4 
@WisamAbbasi, is the variable explorer working for you?
@dalthviz, could you check if you can reproduce this error with our Windows installer (see issue #16272) and Anaconda?
@impact27, do you have an idea about what's happening here?
@ccordoba12 I was unable to reproduce this (is working for me with the installer and anaconda/conda-forge).
@WisamAbbasi, @Galganom, @Walberf17, @ninad-sc, is the variable explorer working for you? I mean, if you evaluate `a = 1` in the console, do you see that variable displayed in the Variable Explorer?
I can't initialize any other thing because there is no connection on
kernel, so I can't do anything.

Em ter, 24 de ago de 2021 12:24, Carlos Cordoba ***@***.***>
escreveu:

> @WisamAbbasi <https://github.com/WisamAbbasi>, @Galganom
> <https://github.com/Galganom>, @Walberf17 <https://github.com/Walberf17>,
> @ninad-sc <https://github.com/ninad-sc>, is the variable explorer working
> for you? I mean, if you evaluate a = 1 in the console, do you see that
> variable displayed in the Variable Explorer?
>
> —
> You are receiving this because you were mentioned.
> Reply to this email directly, view it on GitHub
> <https://github.com/spyder-ide/spyder/issues/15875#issuecomment-904740787>,
> or unsubscribe
> <https://github.com/notifications/unsubscribe-auth/ATJ4Q3XNZTFM3STTDTCXDWLT6O2TVANCNFSM46XQETXQ>
> .
> Triage notifications on the go with GitHub Mobile for iOS
> <https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
> or Android
> <https://play.google.com/store/apps/details?id=com.github.android&utm_campaign=notification-email>
> .
>

Ok, that's expected. Then this problem is probably caused by your firewall or antivirus. Please deactivate them and try again.
Sorry for the late answer, I tried what you suggested, but no results...

Em qua, 25 de ago de 2021 01:07, Carlos Cordoba ***@***.***>
escreveu:

> Ok, that's expected. Then this problem is probably caused by your firewall
> or antivirus. Please deactivate them and try again.
>
> —
> You are receiving this because you were mentioned.
> Reply to this email directly, view it on GitHub
> <https://github.com/spyder-ide/spyder/issues/15875#issuecomment-905165534>,
> or unsubscribe
> <https://github.com/notifications/unsubscribe-auth/ATJ4Q3V3EIYDX7HC5G7RGMLT6RT6RANCNFSM46XQETXQ>
> .
> Triage notifications on the go with GitHub Mobile for iOS
> <https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
> or Android
> <https://play.google.com/store/apps/details?id=com.github.android&utm_campaign=notification-email>
> .
>

Sorry, I don't have more advice for you. But this is definitely not a problem in Spyder.
Ok, thanks.

Em qua, 25 de ago de 2021 10:45, Carlos Cordoba ***@***.***>
escreveu:

> Sorry, I don't have more advice for you. But this definitely not a problem
> in Spyder.
>
> —
> You are receiving this because you were mentioned.
> Reply to this email directly, view it on GitHub
> <https://github.com/spyder-ide/spyder/issues/15875#issuecomment-905514973>,
> or unsubscribe
> <https://github.com/notifications/unsubscribe-auth/ATJ4Q3XAIBYWYAXX7ADLWPTT6TXXFANCNFSM46XQETXQ>
> .
> Triage notifications on the go with GitHub Mobile for iOS
> <https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
> or Android
> <https://play.google.com/store/apps/details?id=com.github.android&utm_campaign=notification-email>
> .
>


Resolving patch:
diff --git a/external-deps/spyder-kernels/spyder_kernels/console/kernel.py b/external-deps/spyder-kernels/spyder_kernels/console/kernel.py
--- a/external-deps/spyder-kernels/spyder_kernels/console/kernel.py
+++ b/external-deps/spyder-kernels/spyder_kernels/console/kernel.py
@@ -718,6 +718,7 @@ def _set_mpl_backend(self, backend, pylab=False):
         """
         import traceback
         from IPython.core.getipython import get_ipython
+        import matplotlib
 
         generic_error = (
             "\n" + "="*73 + "\n"
@@ -730,12 +731,16 @@ def _set_mpl_backend(self, backend, pylab=False):
 
         error = None
         try:
+            # This prevents Matplotlib to automatically set the backend, which
+            # overrides our own mechanism.
+            matplotlib.rcParams['backend'] = 'Agg'
+
+            # Set the backend
             get_ipython().run_line_magic(magic, backend)
         except RuntimeError as err:
             # This catches errors generated by ipykernel when
             # trying to set a backend. See issue 5541
             if "GUI eventloops" in str(err):
-                import matplotlib
                 previous_backend = matplotlib.get_backend()
                 if not backend in previous_backend.lower():
                     # Only inform about an error if the user selected backend
@@ -748,7 +753,6 @@ def _set_mpl_backend(self, backend, pylab=False):
                         "in use.\n\n"
                         "Your backend will be {0}".format(previous_backend)
                     )
-                del matplotlib
             # This covers other RuntimeError's
             else:
                 error = generic_error.format(traceback.format_exc())
diff --git a/external-deps/spyder-kernels/spyder_kernels/utils/mpl.py b/external-deps/spyder-kernels/spyder_kernels/utils/mpl.py
--- a/external-deps/spyder-kernels/spyder_kernels/utils/mpl.py
+++ b/external-deps/spyder-kernels/spyder_kernels/utils/mpl.py
@@ -18,9 +18,16 @@
 }
 
 
+# Inline backend
+if is_module_installed('matplotlib_inline'):
+    inline_backend = 'module://matplotlib_inline.backend_inline'
+else:
+    inline_backend = 'module://ipykernel.pylab.backend_inline'
+
+
 # Mapping of matlotlib backends options to Spyder
 MPL_BACKENDS_TO_SPYDER = {
-    'module://ipykernel.pylab.backend_inline': 0,
+    inline_backend: 0,
     'Qt5Agg': 2,
     'Qt4Agg': 3,
     'MacOSX': 4,


Test patch:
diff --git a/external-deps/spyder-kernels/requirements/tests.txt b/external-deps/spyder-kernels/requirements/tests.txt
--- a/external-deps/spyder-kernels/requirements/tests.txt
+++ b/external-deps/spyder-kernels/requirements/tests.txt
@@ -11,3 +11,5 @@ pytest-cov
 scipy
 xarray
 pillow
+# Remove when Anaconda updates to a newer ipykernel
+ipython_genutils
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
@@ -141,6 +141,11 @@ def __getattr__(self, attr):
     if auto_backend:
         CONF.set('ipython_console', 'pylab/backend', 1)
 
+    # Use the Tkinter backend if requested
+    tk_backend = request.node.get_closest_marker('tk_backend')
+    if tk_backend:
+        CONF.set('ipython_console', 'pylab/backend', 8)
+
     # Start a Pylab client if requested
     pylab_client = request.node.get_closest_marker('pylab_client')
     is_pylab = True if pylab_client else False
@@ -296,21 +301,39 @@ def test_get_calltips(ipyconsole, qtbot, function, signature, documentation):
 @flaky(max_runs=3)
 @pytest.mark.auto_backend
 def test_auto_backend(ipyconsole, qtbot):
-    """Test that the automatic backend is working correctly."""
+    """Test that the automatic backend was set correctly."""
     # Wait until the window is fully up
     shell = ipyconsole.get_current_shellwidget()
     qtbot.waitUntil(lambda: shell._prompt_html is not None,
                     timeout=SHELL_TIMEOUT)
 
     with qtbot.waitSignal(shell.executed):
-        shell.execute("import matplotlib; matplotlib.get_backend()")
+        shell.execute("ip = get_ipython(); ip.kernel.eventloop")
 
     # Assert there are no errors in the console and we set the right
     # backend.
     control = ipyconsole.get_focus_widget()
     assert 'NOTE' not in control.toPlainText()
     assert 'Error' not in control.toPlainText()
-    assert 'Qt5Agg' in control.toPlainText()
+    assert 'loop_qt5' in control.toPlainText()
+
+
+@flaky(max_runs=3)
+@pytest.mark.tk_backend
+@pytest.mark.skipif(os.name == 'nt', reason="Fails on Windows")
+def test_tk_backend(ipyconsole, qtbot):
+    """Test that the Tkinter backend was set correctly."""
+    # Wait until the window is fully up
+    shell = ipyconsole.get_current_shellwidget()
+    qtbot.waitUntil(lambda: shell._prompt_html is not None,
+                    timeout=SHELL_TIMEOUT)
+
+    with qtbot.waitSignal(shell.executed):
+        shell.execute("ip = get_ipython(); ip.kernel.eventloop")
+
+    # Assert we set the right backend in the kernel.
+    control = ipyconsole.get_focus_widget()
+    assert 'loop_tk' in control.toPlainText()
 
 
 @flaky(max_runs=3)