Repository: spyder-ide/spyder

Issue:
Inconsistent debugger behavior
Inside debugger
<img src="https://user-images.githubusercontent.com/16495490/141040239-b726e81f-f2cf-4105-b734-889f19796338.png" width="600">

but outside, it's a consistent

<img src="https://user-images.githubusercontent.com/16495490/141040324-e3ab121e-21b2-4339-b7e7-62df90c4fb5b.png" width="600">

Data [here](https://ufile.io/5tgtitk2). Code

```python
import numpy as np  # IPdb[1]

def energy(x):  # IPdb[2]
    return np.sum(np.abs(x)**2)

coefs0 = np.load('coefs0.npy')  # IPdb[3]
coefs1 = np.load('coefs1.npy')

for i, c0 in enumerate(coefs0):  # IPdb[4]
    assert np.any([np.allclose(energy(c0), energy(c1)) for c1 in coefs1]), i
```

Windows 10, Python 3.8.12, minimal install `conda create -y -n spy5 spyder==5.1.5 -c conda-forge` plus `conda install -c conda-forge numpy`

<details>
  <summary><b>conda list</b></summary>

```
# packages in environment at D:\Anaconda\envs\spy5:
#
# Name                    Version                   Build  Channel
alabaster                 0.7.12                     py_0    conda-forge
argh                      0.26.2          pyh9f0ad1d_1002    conda-forge
arrow                     1.2.0              pyhd8ed1ab_0    conda-forge
astroid                   2.5.8            py38haa244fe_0    conda-forge
async_generator           1.10                       py_0    conda-forge
atomicwrites              1.4.0              pyh9f0ad1d_0    conda-forge
attrs                     21.2.0             pyhd8ed1ab_0    conda-forge
autopep8                  1.5.7              pyhd8ed1ab_0    conda-forge
babel                     2.9.1              pyh44b312d_0    conda-forge
backcall                  0.2.0              pyh9f0ad1d_0    conda-forge
backports                 1.0                        py_2    conda-forge
backports.functools_lru_cache 1.6.4              pyhd8ed1ab_0    conda-forge
bcrypt                    3.2.0            py38h294d835_1    conda-forge
binaryornot               0.4.4                      py_1    conda-forge
black                     21.9b0             pyhd8ed1ab_1    conda-forge
bleach                    4.1.0              pyhd8ed1ab_0    conda-forge
brotlipy                  0.7.0           py38h294d835_1001    conda-forge
ca-certificates           2021.10.26           haa95532_2
certifi                   2021.10.8        py38haa244fe_1    conda-forge
cffi                      1.14.6           py38hd8c33c5_1    conda-forge
chardet                   4.0.0            py38haa244fe_1    conda-forge
charset-normalizer        2.0.0              pyhd8ed1ab_0    conda-forge
click                     8.0.3            py38haa244fe_0    conda-forge
cloudpickle               2.0.0              pyhd8ed1ab_0    conda-forge
colorama                  0.4.4              pyh9f0ad1d_0    conda-forge
cookiecutter              1.6.0                 py38_1000    conda-forge
cryptography              35.0.0           py38hd7da0ea_0    conda-forge
dataclasses               0.8                pyhc8e2a94_3    conda-forge
debugpy                   1.4.1            py38h885f38d_0    conda-forge
decorator                 5.1.0              pyhd8ed1ab_0    conda-forge
defusedxml                0.7.1              pyhd8ed1ab_0    conda-forge
diff-match-patch          20200713           pyh9f0ad1d_0    conda-forge
docutils                  0.17.1           py38haa244fe_0    conda-forge
entrypoints               0.3             pyhd8ed1ab_1003    conda-forge
flake8                    3.9.2              pyhd8ed1ab_0    conda-forge
future                    0.18.2           py38haa244fe_3    conda-forge
icu                       68.1                 h0e60522_0    conda-forge
idna                      3.1                pyhd3deb0d_0    conda-forge
imagesize                 1.2.0                      py_0    conda-forge
importlib-metadata        4.8.1            py38haa244fe_0    conda-forge
importlib_metadata        4.8.1                hd8ed1ab_0    conda-forge
inflection                0.5.1              pyh9f0ad1d_0    conda-forge
intel-openmp              2021.4.0          h57928b3_3556    conda-forge
intervaltree              3.0.2                      py_0    conda-forge
ipykernel                 6.4.1            py38h595d716_0    conda-forge
ipython                   7.28.0           py38h595d716_0    conda-forge
ipython_genutils          0.2.0                      py_1    conda-forge
isort                     5.9.3              pyhd8ed1ab_0    conda-forge
jedi                      0.18.0           py38haa244fe_2    conda-forge
jinja2                    3.0.2              pyhd8ed1ab_0    conda-forge
jinja2-time               0.2.0                      py_2    conda-forge
jpeg                      9d                   h8ffe710_0    conda-forge
jsonschema                4.1.0              pyhd8ed1ab_0    conda-forge
jupyter_client            6.1.12             pyhd8ed1ab_0    conda-forge
jupyter_core              4.8.1            py38haa244fe_0    conda-forge
jupyterlab_pygments       0.1.2              pyh9f0ad1d_0    conda-forge
keyring                   23.2.1           py38haa244fe_0    conda-forge
lazy-object-proxy         1.6.0            py38h294d835_0    conda-forge
libblas                   3.9.0              12_win64_mkl    conda-forge
libcblas                  3.9.0              12_win64_mkl    conda-forge
libclang                  11.1.0          default_h5c34c98_1    conda-forge
liblapack                 3.9.0              12_win64_mkl    conda-forge
libpng                    1.6.37               h1d00b33_2    conda-forge
libsodium                 1.0.18               h8d14728_1    conda-forge
libspatialindex           1.9.3                h39d44d4_4    conda-forge
libzlib                   1.2.11            h8ffe710_1013    conda-forge
markupsafe                2.0.1            py38h294d835_0    conda-forge
matplotlib-inline         0.1.3              pyhd8ed1ab_0    conda-forge
mccabe                    0.6.1                      py_1    conda-forge
mistune                   0.8.4           py38h294d835_1004    conda-forge
mkl                       2021.4.0           h0e2418a_729    conda-forge
mypy_extensions           0.4.3            py38haa244fe_3    conda-forge
nbclient                  0.5.4              pyhd8ed1ab_0    conda-forge
nbconvert                 6.2.0            py38haa244fe_0    conda-forge
nbformat                  5.1.3              pyhd8ed1ab_0    conda-forge
nest-asyncio              1.5.1              pyhd8ed1ab_0    conda-forge
numpy                     1.21.4           py38h089cfbf_0    conda-forge
numpydoc                  1.1.0                      py_1    conda-forge
openssl                   1.1.1l               h8ffe710_0    conda-forge
packaging                 21.0               pyhd8ed1ab_0    conda-forge
pandoc                    2.14.2               h8ffe710_0    conda-forge
pandocfilters             1.5.0              pyhd8ed1ab_0    conda-forge
paramiko                  2.8.0              pyhd8ed1ab_0    conda-forge
parso                     0.8.2              pyhd8ed1ab_0    conda-forge
pathspec                  0.9.0              pyhd8ed1ab_0    conda-forge
pexpect                   4.8.0              pyh9f0ad1d_2    conda-forge
pickleshare               0.7.5                   py_1003    conda-forge
pip                       21.3               pyhd8ed1ab_0    conda-forge
platformdirs              2.3.0              pyhd8ed1ab_0    conda-forge
pluggy                    1.0.0            py38haa244fe_1    conda-forge
poyo                      0.5.0                      py_0    conda-forge
prompt-toolkit            3.0.20             pyha770c72_0    conda-forge
psutil                    5.8.0            py38h294d835_1    conda-forge
ptyprocess                0.7.0              pyhd3deb0d_0    conda-forge
pycodestyle               2.7.0              pyhd8ed1ab_0    conda-forge
pycparser                 2.20               pyh9f0ad1d_2    conda-forge
pydocstyle                6.1.1              pyhd8ed1ab_0    conda-forge
pyflakes                  2.3.1              pyhd8ed1ab_0    conda-forge
pygments                  2.10.0             pyhd8ed1ab_0    conda-forge
pylint                    2.7.2            py38haa244fe_0    conda-forge
pyls-spyder               0.4.0              pyhd8ed1ab_0    conda-forge
pynacl                    1.4.0            py38h31c79cd_2    conda-forge
pyopenssl                 21.0.0             pyhd8ed1ab_0    conda-forge
pyparsing                 2.4.7              pyh9f0ad1d_0    conda-forge
pyqt                      5.12.3           py38haa244fe_7    conda-forge
pyqt-impl                 5.12.3           py38h885f38d_7    conda-forge
pyqt5-sip                 4.19.18          py38h885f38d_7    conda-forge
pyqtchart                 5.12             py38h885f38d_7    conda-forge
pyqtwebengine             5.12.1           py38h885f38d_7    conda-forge
pyrsistent                0.17.3           py38h294d835_2    conda-forge
pysocks                   1.7.1            py38haa244fe_3    conda-forge
python                    3.8.12          h7840368_2_cpython    conda-forge
python-dateutil           2.8.2              pyhd8ed1ab_0    conda-forge
python-lsp-black          1.0.0              pyhd8ed1ab_0    conda-forge
python-lsp-jsonrpc        1.0.0              pyhd8ed1ab_0    conda-forge
python-lsp-server         1.2.4              pyhd8ed1ab_0    conda-forge
python_abi                3.8                      2_cp38    conda-forge
pytz                      2021.3             pyhd8ed1ab_0    conda-forge
pywin32                   301              py38h294d835_0    conda-forge
pywin32-ctypes            0.2.0           py38haa244fe_1003    conda-forge
pyyaml                    6.0              py38h294d835_0    conda-forge
pyzmq                     22.3.0           py38h09162b1_0    conda-forge
qdarkstyle                3.0.2              pyhd8ed1ab_0    conda-forge
qstylizer                 0.2.1              pyhd8ed1ab_0    conda-forge
qt                        5.12.9               h5909a2a_4    conda-forge
qtawesome                 1.0.3              pyhd8ed1ab_0    conda-forge
qtconsole                 5.1.1              pyhd8ed1ab_0    conda-forge
qtpy                      1.11.2             pyhd8ed1ab_0    conda-forge
regex                     2021.10.8        py38h294d835_0    conda-forge
requests                  2.26.0             pyhd8ed1ab_0    conda-forge
rope                      0.21.0             pyhd8ed1ab_0    conda-forge
rtree                     0.9.7            py38h8b54edf_2    conda-forge
setuptools                58.2.0           py38haa244fe_0    conda-forge
six                       1.16.0             pyh6c4a22f_0    conda-forge
snowballstemmer           2.1.0              pyhd8ed1ab_0    conda-forge
sortedcontainers          2.4.0              pyhd8ed1ab_0    conda-forge
sphinx                    4.2.0              pyh6c4a22f_0    conda-forge
sphinxcontrib-applehelp   1.0.2                      py_0    conda-forge
sphinxcontrib-devhelp     1.0.2                      py_0    conda-forge
sphinxcontrib-htmlhelp    2.0.0              pyhd8ed1ab_0    conda-forge
sphinxcontrib-jsmath      1.0.1                      py_0    conda-forge
sphinxcontrib-qthelp      1.0.3                      py_0    conda-forge
sphinxcontrib-serializinghtml 1.1.5              pyhd8ed1ab_0    conda-forge
spyder                    5.1.5            py38haa244fe_0    conda-forge
spyder-kernels            2.1.3            py38haa244fe_0    conda-forge
sqlite                    3.36.0               h8ffe710_2    conda-forge
tbb                       2021.4.0             h2d74725_1    conda-forge
testpath                  0.5.0              pyhd8ed1ab_0    conda-forge
textdistance              4.2.1              pyhd8ed1ab_0    conda-forge
three-merge               0.1.1              pyh9f0ad1d_0    conda-forge
tinycss2                  1.1.0              pyhd8ed1ab_0    conda-forge
toml                      0.10.2             pyhd8ed1ab_0    conda-forge
tomli                     1.2.1              pyhd8ed1ab_0    conda-forge
tornado                   6.1              py38h294d835_1    conda-forge
traitlets                 5.1.0              pyhd8ed1ab_0    conda-forge
typed-ast                 1.4.3            py38h294d835_0    conda-forge
typing_extensions         3.10.0.2           pyha770c72_0    conda-forge
ucrt                      10.0.20348.0         h57928b3_0    conda-forge
ujson                     4.2.0            py38h885f38d_0    conda-forge
urllib3                   1.26.7             pyhd8ed1ab_0    conda-forge
vc                        14.2                 hb210afc_5    conda-forge
vs2015_runtime            14.29.30037          h902a5da_5    conda-forge
watchdog                  2.1.6            py38haa244fe_0    conda-forge
wcwidth                   0.2.5              pyh9f0ad1d_2    conda-forge
webencodings              0.5.1                      py_1    conda-forge
wheel                     0.37.0             pyhd8ed1ab_1    conda-forge
whichcraft                0.6.1                      py_0    conda-forge
win_inet_pton             1.1.0            py38haa244fe_2    conda-forge
wrapt                     1.12.1           py38h294d835_3    conda-forge
yaml                      0.2.5                he774522_0    conda-forge
yapf                      0.31.0             pyhd8ed1ab_0    conda-forge
zeromq                    4.3.4                h0e60522_1    conda-forge
zipp                      3.6.0              pyhd8ed1ab_0    conda-forge
zlib                      1.2.11            h8ffe710_1013    conda-forge
```
</details>


Discussion:
Hi @OverLordGoldDragon thanks for the feedback! I was able to reproduce this (not totally sure though why it could be happening).

Also, while testing, if I just run the code from a file using the `Debug` or `Debug cell` actions I get the `AssertionError 5` message.

Maybe this related with the handling of variables inside a `for` when directly using the IPdb prompt? (the first run  shows a `*** NameError: name 'c0' is not defined`)

Maybe @ccordoba12 or @impact27 have some ideas to check what could be happening?
With our mitigations for https://bugs.python.org/issue41918:
```python
In [1]: import numpy as np
   ...: a = np.arange(3)
   ...: b = np.arange(3) * 10

In [2]: %debug print
NOTE: Enter 'c' at the ipdb>  prompt to continue execution.
> <string>(1)<module>()


IPdb [1]: for c0 in a: print([(c0, c1) for c1 in b])
*** NameError: name 'c0' is not defined

IPdb [2]: for c0 in a: print([(c0, c1) for c1 in b])
[(0, 0), (0, 10), (0, 20)]
[(0, 0), (0, 10), (0, 20)]
[(0, 0), (0, 10), (0, 20)]

IPdb [3]: 
```

Without:
```python
In [2]: import numpy as np
   ...: a = np.arange(3)
   ...: b = np.arange(3) * 10
In [3]: %debug print
NOTE: Enter 'c' at the ipdb>  prompt to continue execution.
> <string>(1)<module>()


IPdb [1]: for c0 in a: print([(c0, c1) for c1 in b])
[(0, 0), (0, 10), (0, 20)]
[(1, 0), (1, 10), (1, 20)]
[(2, 0), (2, 10), (2, 20)]

IPdb [2]: 
```

see https://github.com/spyder-ide/spyder-kernels/blob/5bae6d34a287afbbdfde38c1d7b219461371bc52/spyder_kernels/customize/spyderpdb.py#L200
I think what @impact27 means is that this is related to the usage of list comprehensions inside the debugger.

@impact27, is there something else we can do about this?
Seeing this: 
```python
In [2]: import numpy as np

In [3]: exec("for c0 in a: print([(c0, c1) for c1 in b])", {"a": np.arange(3), "b": np.arange(3) * 10})
[(0, 0), (0, 10), (0, 20)]
[(1, 0), (1, 10), (1, 20)]
[(2, 0), (2, 10), (2, 20)]

In [4]: exec("for c0 in a: print([(c0, c1) for c1 in b])", {"a": np.arange(3), "b": np.arange(3) * 10}, {})
Traceback (most recent call last):

  File "/var/folders/xx/mbs7xxcs2397g51c4kbg23p00000gp/T/ipykernel_33146/640046553.py", line 1, in <module>
    exec("for c0 in a: print([(c0, c1) for c1 in b])", {"a": np.arange(3), "b": np.arange(3) * 10}, {})

  File "<string>", line 1, in <module>

  File "<string>", line 1, in <listcomp>

NameError: name 'c0' is not defined


In [5]: 
```
I think we should not give locals when running code that has comprehensions.

Resolving patch:
diff --git a/external-deps/spyder-kernels/spyder_kernels/customize/spyderpdb.py b/external-deps/spyder-kernels/spyder_kernels/customize/spyderpdb.py
--- a/external-deps/spyder-kernels/spyder_kernels/customize/spyderpdb.py
+++ b/external-deps/spyder-kernels/spyder_kernels/customize/spyderpdb.py
@@ -205,13 +205,16 @@ def default(self, line):
                     # 2. Any edit to that variable will be lost.
                     # 3. The globals will appear to contain all the locals
                     #    variables.
+                    # 4. Any new locals variable will be saved to globals
+                    #    instead
                     fake_globals = globals.copy()
                     fake_globals.update(locals)
                     locals_keys = locals.keys()
-                    exec(code, fake_globals, locals)
+                    # Don't pass locals, solves spyder-ide/spyder#16790
+                    exec(code, fake_globals)
                     # Avoid mixing locals and globals
                     for key in locals_keys:
-                        fake_globals.pop(key, None)
+                        locals[key] = fake_globals.pop(key, None)
                     globals.update(fake_globals)
                 else:
                     exec(code, globals, locals)


Test patch:
diff --git a/external-deps/spyder-kernels/spyder_kernels/console/tests/test_console_kernel.py b/external-deps/spyder-kernels/spyder_kernels/console/tests/test_console_kernel.py
--- a/external-deps/spyder-kernels/spyder_kernels/console/tests/test_console_kernel.py
+++ b/external-deps/spyder-kernels/spyder_kernels/console/tests/test_console_kernel.py
@@ -829,6 +829,30 @@ def test_comprehensions_with_locals_in_pdb(kernel):
     pdb_obj.curframe = None
     pdb_obj.curframe_locals = None
 
+def test_comprehensions_with_locals_in_pdb_2(kernel):
+    """
+    Test that evaluating comprehensions with locals works in Pdb.
+
+    This is a regression test for spyder-ide/spyder#16790.
+    """
+    pdb_obj = SpyderPdb()
+    pdb_obj.curframe = inspect.currentframe()
+    pdb_obj.curframe_locals = pdb_obj.curframe.f_locals
+    kernel.shell.pdb_session = pdb_obj
+
+    # Create a local variable.
+    kernel.shell.pdb_session.default('aa = [1, 2]')
+    kernel.shell.pdb_session.default('bb = [3, 4]')
+    kernel.shell.pdb_session.default('res = []')
+
+    # Run a list comprehension with this variable.
+    kernel.shell.pdb_session.default(
+        "for c0 in aa: res.append([(c0, c1) for c1 in bb])")
+    assert kernel.get_value('res') == [[(1, 3), (1, 4)], [(2, 3), (2, 4)]]
+
+    pdb_obj.curframe = None
+    pdb_obj.curframe_locals = None
+
 
 def test_namespaces_in_pdb(kernel):
     """
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
@@ -624,7 +624,8 @@ def test_get_help_ipython_console_dot_notation(main_window, qtbot, tmpdir):
 
 
 @pytest.mark.slow
-@pytest.mark.skipif(PY2, reason="Invalid definition of function in Python 2.")
+@flaky(max_runs=3)
+@pytest.mark.skipif(sys.platform == 'darwin', reason="Too flaky on Mac")
 def test_get_help_ipython_console_special_characters(
         main_window, qtbot, tmpdir):
     """