Repository: spyder-ide/spyder

Issue:
Removing all variables on remote kernels fails
## Description

### What steps will reproduce the problem?

<!--- You can use Markdown here --->

1. Connect to a remote kernel: click on menu "Console"-> "connect to an existing kernel". Choose a connection file, tick "this is a remote kernel (via SSH)". Use password authentication.  The remote kernel runs on an Ubuntu machine in the same network. 
2. Run code (specifically: tensorflow_hub model)
3. In the console panel, click on the menu and then "remove all variables"

### Traceback
```python-traceback
  File "C:\Users\tkora\Anaconda3\envs\s4\lib\site-packages\spyder\plugins\ipythonconsole\plugin.py", line 1213, in reset_kernel
    client.reset_namespace()
  File "C:\Users\tkora\Anaconda3\envs\s4\lib\site-packages\spyder\plugins\ipythonconsole\widgets\client.py", line 596, in reset_namespace
    message=True)
  File "C:\Users\tkora\Anaconda3\envs\s4\lib\site-packages\spyder\plugins\ipythonconsole\widgets\shell.py", line 242, in reset_namespace
    kernel_env = self.kernel_manager._kernel_spec.env
AttributeError: 'NoneType' object has no attribute '_kernel_spec'
```

## Versions

* Spyder version: 4.0.0b2 
* Python version: 3.7.3
* Qt version: 5.9.6
* PyQt5 version: 5.9.2
* Operating System: Windows 10

### Dependencies

```
pygments >=2.0     :  2.4.0 (OK)
qdarkstyle >=2.6.4 :  2.6.8 (OK)
sphinx >=0.6.6     :  2.0.1 (OK)
pyls >=0.19.0;<0.25:  0.24.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      :  None (NOK)
cython >=0.21      :  None (NOK)
qtconsole >=4.2.0  :  4.5.1 (OK)
IPython >=4.0      :  7.5.0 (OK)
matplotlib >=2.0.0 :  None (NOK)
pylint >=0.25      :  2.3.1 (OK)
```



Discussion:
> Connect to a remote kernel

Please clarify how you connected to a remote kernel.
> > Connect to a remote kernel
> 
> Please clarify how you connected to a remote kernel.

Added details to the description. Let me know if specific details are needed. 
Ok, thanks for the update. But how did you started the remote kernel? I mean, what command did you use to do that?
> Ok, thanks for the update. But how did you started the remote kernel? I mean, what command did you use to do that?

from an anaconda environment:
ipython kernel -f <path to the connection specification JSON file>
> ipython kernel -f 

Thanks, that's what I thought.
@juanis2112, please take a look at this bug.

The idea is the enclose this line

https://github.com/spyder-ide/spyder/blob/644cd3459f296bd9d5ff752f0c3b33beb9768815/spyder/plugins/ipythonconsole/widgets/shell.py#L242

in a `try/except AttributeError`, and in the except part assign an empty dictionary to `kernel_env`.

To test if things are working as expected, you can create an external kernel in a terminal with the command

    ipython kernel

then connect to that kernel using our dialog in the menu `Consoles > Connect to an existing kernel` and finally going to the Options menu of the IPython console and selecting `Remove all variables`.

Resolving patch:
diff --git a/spyder/plugins/ipythonconsole/widgets/shell.py b/spyder/plugins/ipythonconsole/widgets/shell.py
--- a/spyder/plugins/ipythonconsole/widgets/shell.py
+++ b/spyder/plugins/ipythonconsole/widgets/shell.py
@@ -239,7 +239,13 @@ def reset_namespace(self, warning=False, message=False):
         reset_str = _("Remove all variables")
         warn_str = _("All user-defined variables will be removed. "
                      "Are you sure you want to proceed?")
-        kernel_env = self.kernel_manager._kernel_spec.env
+        # This is necessary to make resetting variables work in external
+        # kernels.
+        # See spyder-ide/spyder#9505
+        try:
+            kernel_env = self.kernel_manager._kernel_spec.env
+        except AttributeError:
+            kernel_env = {}
 
         if warning:
             box = MessageCheckBox(icon=QMessageBox.Warning, parent=self)


Test patch: