Repository: spyder-ide/spyder

Issue:
Cannot runcell if double backslash is present
<!--- **PLEASE READ:** When submitting here, please ensure you've completed the following checklist and checked the boxes to confirm. Issue reports without it may be closed. Thanks! --->

### Issue Report Checklist

* [x] Searched the [issues page](https://github.com/spyder-ide/spyder/issues?q=is%3Aissue) for similar reports
* [x] Completed the **Problem Description**, **Steps to Reproduce** and **Version** sections below


## Problem Description

@bcolsen

I think this was introduced in PR https://github.com/spyder-ide/spyder/pull/7310. I was not able to reproduce the error when checking out to https://github.com/spyder-ide/spyder/commit/29e06238763bb58c003c70c70fd59dc1458386fb.



### What steps reproduce the problem?

1. Create a new file with the following content in the Editor :

```python
# -*- coding: utf-8 -*-
#%%

dirname = ("C:\\Users\\User\\test.py")

# %%
```

2. Run the cell (`Ctrl + Enter` or `Shift + Enter`).

### What is the expected output? What do you see instead?

`dirname` should be defined in the current console, but an error is raised instead.


### Paste Traceback/Error Below (if applicable)
<!--- Copy from error dialog or View > Panes > Internal Console --->

```python-traceback
runcell('','C:/Users/User/Desktop/test.py')
  File "<ipython-input-26-0a3ec57e3b80>", line 4
    dirname = ("C:\Users\User\test.py")
              ^
SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 2-3: truncated \UXXXXXXXX escape
```

## Versions
<!--- You can get this information from Help > About Spyder...
or (if Spyder won't launch) the "conda list" command
from the Anaconda Prompt/Terminal/command line. --->

* Spyder version: Spyder 4.0.0.dev0  https://github.com/spyder-ide/spyder/commit/44793430dff620e8031caacfed2338c54c77d2a8
* Python version: Python 3.6.6 64-bit
* Qt version: Qt 5.6.2 
* PyQt version: PyQt5 5.6
* Operating System name/version:  Windows 10 

### Dependencies
<!--- Please go to the menu entry Help > Dependencies,
press the Copy to clipboard button and paste below --->

```
pygments >=2.0    :  2.2.0 (OK)
sphinx >=0.6.6    :  1.8.1 (OK)
pyls >=0.19.0     :  0.19.0 (OK)
nbconvert >=4.0   :  5.3.1 (OK)
pandas >=0.13.1   :  0.23.4 (OK)
numpy >=1.7       :  1.15.2 (OK)
sympy >=0.7.3     :  None (NOK)
cython >=0.21     :  None (NOK)
qtconsole >=4.2.0 :  4.5.0.dev0 (OK)
IPython >=4.0     :  7.0.1 (OK)
matplotlib >=2.0.0:  None (NOK)
pylint >=0.25     :  2.1.1 (OK)
```



Discussion:
@bcolsen, could you take a look at this one? Thanks!
It looks like the escape `/`'s are being remove before running the cell.

I get the same error running: 
```
In [112]: dirname = ('C:\Users\User\test.py')
  File "<ipython-input-112-09e9a480868a>", line 1
    dirname = ('C:\Users\User\test.py')
              ^
SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 2-3: truncated \UXXXXXXXX escape
```
I can test this tonight but I think a ` 'r"""{}"""')` on this line might work:
https://github.com/spyder-ide/spyder/blob/4733c44459a086a1d60bea53f594d207b6ff9028/spyder/plugins/ipythonconsole/plugin.py#L939


Yep, I was thinking an `r` would help to solve this.
Cool, thank you very much for taking care of this! This is a little bit annoying hehe

Resolving patch:
diff --git a/spyder/plugins/ipythonconsole/plugin.py b/spyder/plugins/ipythonconsole/plugin.py
--- a/spyder/plugins/ipythonconsole/plugin.py
+++ b/spyder/plugins/ipythonconsole/plugin.py
@@ -936,7 +936,7 @@ def norm(text):
                     if is_internal_kernel:
                         client.shellwidget.silent_execute(
                             to_text_string('get_ipython().cell_code = '
-                                           '"""{}"""')
+                                           'r"""{}"""')
                                 .format(to_text_string(code)
                                 .replace('"""', r'\"\"\"')))
                     self.execute_code(line)


Test patch:
diff --git a/spyder/app/tests/script.py b/spyder/app/tests/script.py
--- a/spyder/app/tests/script.py
+++ b/spyder/app/tests/script.py
@@ -5,9 +5,10 @@
 # In[23]
 li = [1, 2, 3]
 
-# <codecell> Third Code Cell's name
+# <codecell> Third Code Cell\'s name
 import numpy as np
 arr = np.array(li)
 
 #%% Fourth Code/ Cell's % name\
+s = "Z:\\escape\\test\\string\n"
 a
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
@@ -545,7 +545,7 @@ def test_dedicated_consoles(main_window, qtbot):
     assert main_window.ipyconsole.filenames == ['', test_file]
     assert main_window.ipyconsole.tabwidget.tabText(1) == 'script.py/A'
     qtbot.wait(500)
-    assert nsb.editor.model.rowCount() == 3
+    assert nsb.editor.model.rowCount() == 4
 
     # --- Assert only runfile text is present and there's no banner text ---
     # See PR #5301
@@ -890,11 +890,12 @@ def test_run_code(main_window, qtbot, tmpdir):
     qtbot.keyClick(code_editor, Qt.Key_F5)
 
     # Wait until all objects have appeared in the variable explorer
-    qtbot.waitUntil(lambda: nsb.editor.model.rowCount() == 3,
+    qtbot.waitUntil(lambda: nsb.editor.model.rowCount() == 4,
                     timeout=EVAL_TIMEOUT)
 
     # Verify result
     assert shell.get_value('a') == 10
+    assert shell.get_value('s') == "Z:\\escape\\test\\string\n"
     assert shell.get_value('li') == [1, 2, 3]
     assert_array_equal(shell.get_value('arr'), np.array([1, 2, 3]))
 
@@ -907,11 +908,12 @@ def test_run_code(main_window, qtbot, tmpdir):
         qtbot.wait(200)
 
     # Wait until all objects have appeared in the variable explorer
-    qtbot.waitUntil(lambda: nsb.editor.model.rowCount() == 3,
+    qtbot.waitUntil(lambda: nsb.editor.model.rowCount() == 4,
                     timeout=EVAL_TIMEOUT)
 
     # Verify result
     assert shell.get_value('a') == 10
+    assert shell.get_value('s') == "Z:\\escape\\test\\string\n"
     assert shell.get_value('li') == [1, 2, 3]
     assert_array_equal(shell.get_value('arr'), np.array([1, 2, 3]))
 
@@ -928,12 +930,13 @@ def test_run_code(main_window, qtbot, tmpdir):
     assert 'Error:' not in shell._control.toPlainText()
 
     # Wait until all objects have appeared in the variable explorer
-    qtbot.waitUntil(lambda: nsb.editor.model.rowCount() == 3,
+    qtbot.waitUntil(lambda: nsb.editor.model.rowCount() == 4,
                     timeout=EVAL_TIMEOUT)
 
     # Verify result
     assert ']: 10\n' in shell._control.toPlainText()
     assert shell.get_value('a') == 10
+    assert shell.get_value('s') == "Z:\\escape\\test\\string\n"
     assert shell.get_value('li') == [1, 2, 3]
     assert_array_equal(shell.get_value('arr'), np.array([1, 2, 3]))
 
@@ -1029,12 +1032,13 @@ def test_run_cell_copy(main_window, qtbot, tmpdir):
     assert 'Error:' not in shell._control.toPlainText()
 
     # Wait until all objects have appeared in the variable explorer
-    qtbot.waitUntil(lambda: nsb.editor.model.rowCount() == 3,
+    qtbot.waitUntil(lambda: nsb.editor.model.rowCount() == 4,
                     timeout=EVAL_TIMEOUT)
 
     # Verify result
     assert ']: 10\n' in shell._control.toPlainText()
     assert shell.get_value('a') == 10
+    assert shell.get_value('s') == "Z:\\escape\\test\\string\n"
     assert shell.get_value('li') == [1, 2, 3]
     assert_array_equal(shell.get_value('arr'), np.array([1, 2, 3]))
 
@@ -1246,6 +1250,10 @@ def test_c_and_n_pdb_commands(main_window, qtbot):
     qtbot.keyClick(control, Qt.Key_Enter)
     qtbot.wait(500)
 
+    qtbot.keyClicks(control, 'n')
+    qtbot.keyClick(control, Qt.Key_Enter)
+    qtbot.wait(500)
+
     # Assert that the prompt appear
     shell.clear_console()
     assert 'In [2]:' in control.toPlainText()