Repository: spyder-ide/spyder

Issue:
'Execute in an external system terminal' doesn't work if there is spaces in the path where the python interpreter is installed in Windows
<!--- **PLEASE READ:** Before submitting here, please carefully consult our *Troubleshooting Guide* at https://github.com/spyder-ide/spyder/wiki/Troubleshooting-Guide-and-FAQ and search the issues page for your error/problem, as most posted bugs are duplicates or easy fixes.

If you don't find anything, please provide a detailed step-by-step description (in English) of the problem and what led up to it below. Issue reports without a clear way to reproduce them will be closed. Thanks! --->

## Problem Description

I'm trying to execute a script in an external system terminal on Windows 10 64bit and it is not working.

### What steps will reproduce the problem?
Let's say I have this very simple script :
```python
# -*- coding: utf-8 -*-
print('test')
```
1.  Run the script with <kbd>F5</kbd> using the configuration per file shown below so that the script is executed in an external system terminal and so that I can interact with the Python console after execution.

![image](https://user-images.githubusercontent.com/10170372/37351401-5977428a-26b1-11e8-901b-43cdb3e0cbdd.png)

### What is the expected output? What do you see instead?

I expect the script to run in an external system terminal and to be able to see the result in the Python console. Instead, the cmd windows is shown for a fraction of a second, then nothing happens.

### Paste Traceback/Error Below (if applicable)
<!--- Copy from error dialog or View > Panes > Internal Console --->

There is no traceback/error.

## Package Versions

* Spyder: Spyder 4.0.0.dev0 
* Python: Python 3.6.4 64bits
* Qt: Qt 5.9.1
* PyQt: PyQt5 5.9
* Operating System: Windows 10 amd64

### Dependencies
<!--- Please go to the menu entry Help > Dependencies,
press the Copy to clipboard button and paste below --->

```
pyflakes >=0.6.0 :  1.6.0 (OK)
pycodestyle >=2.3:  2.3.1 (OK)
pygments >=2.0   :  2.2.0 (OK)
pandas >=0.13.1  :  0.22.0 (OK)
numpy >=1.7      :  1.14.2 (OK)
sphinx >=0.6.6   :  1.7.1 (OK)
rope >=0.9.4     :  0.10.7 (OK)
jedi >=0.9.0     :  0.11.1 (OK)
nbconvert >=4.0  :  5.3.1 (OK)
sympy >=0.7.3    :  1.1.1 (OK)
cython >=0.21    :  0.27.3 (OK)
qtconsole >=4.2.0:  4.4.0.dev (OK)
IPython >=4.0    :  6.2.1 (OK)
pylint >=0.25    :  1.8.2 (OK)
```



Discussion:
**Why it is not working**

I do not use Anaconda. I've installed Python in `C:\Program Files\Python36` which is a common place where program are installed in Windows.

The command to execute the script in an external system terminal is not working because of the space in `Program Files` .

In the function [run_python_script_in_terminal](https://github.com/spyder-ide/spyder/blob/master/spyder/utils/programs.py#L255) in [spyder/utils/program.py](https://github.com/spyder-ide/spyder/blob/master/spyder/utils/programs.py), I think the path that is returned by `get_python_executable()` should be enclosed in "" to fix this.
> I think the path that is returned by get_python_executable() should be enclosed in "" to fix this.

That seems the right fix. Would you like to submit a PR for this?
@ccordoba12 sure, I'm going to do it today.

Resolving patch:
diff --git a/spyder/app/mainwindow.py b/spyder/app/mainwindow.py
--- a/spyder/app/mainwindow.py
+++ b/spyder/app/mainwindow.py
@@ -157,7 +157,7 @@
 from spyder.utils import icon_manager as ima
 from spyder.utils.introspection import module_completion
 from spyder.utils.programs import is_module_installed
-from spyder.utils.misc import select_port, getcwd_or_home
+from spyder.utils.misc import select_port, getcwd_or_home, get_python_executable
 from spyder.widgets.fileswitcher import FileSwitcher
 
 #==============================================================================
@@ -2532,8 +2532,13 @@ def open_external_console(self, fname, wdir, args, interact, debug, python,
         if systerm:
             # Running script in an external system terminal
             try:
-                programs.run_python_script_in_terminal(fname, wdir, args,
-                                                interact, debug, python_args)
+                if CONF.get('main_interpreter', 'default'):
+                    executable = get_python_executable()
+                else:
+                    executable = CONF.get('main_interpreter', 'executable')
+                programs.run_python_script_in_terminal(
+                        fname, wdir, args, interact, debug, python_args,
+                        executable)
             except NotImplementedError:
                 QMessageBox.critical(self, _("Run"),
                                      _("Running an external system terminal "
diff --git a/spyder/utils/programs.py b/spyder/utils/programs.py
--- a/spyder/utils/programs.py
+++ b/spyder/utils/programs.py
@@ -253,22 +253,26 @@ def get_python_args(fname, python_args, interact, debug, end_args):
 
 
 def run_python_script_in_terminal(fname, wdir, args, interact,
-                                  debug, python_args):
+                                  debug, python_args, executable=None):
     """
     Run Python script in an external system terminal.
 
     :str wdir: working directory, may be empty.
     """
-    # If fname has spaces on it it can't be ran on Windows, so we have to
-    # enclose it in quotes. Also wdir can come with / as os.sep, so we
-    # need to take care of it
+    if executable is None:
+        executable = get_python_executable()
+
+    # If fname or python_exe contains spaces, it can't be ran on Windows, so we
+    # have to enclose them in quotes. Also wdir can come with / as os.sep, so
+    # we need to take care of it.
     if os.name == 'nt':
         fname = '"' + fname + '"'
         wdir = wdir.replace('/', '\\')
-    
-    p_args = [get_python_executable()]
+        executable = '"' + executable + '"'
+
+    p_args = [executable]
     p_args += get_python_args(fname, python_args, interact, debug, args)
-    
+
     if os.name == 'nt':
         cmd = 'start cmd.exe /c "cd %s && ' % wdir + ' '.join(p_args) + '"'
         # Command line and cwd have to be converted to the filesystem


Test patch: