Repository: ipython/ipython

Issue:
Infinite loop when using ipdb on ipython 7.13+
I use pytest with appium and when I use ipdb.set_trace() I'm stuck in a loop:

```
Exception in thread Thread-21249:
Traceback (most recent call last):
  File "/usr/local/Cellar/python/3.7.6_1/Frameworks/Python.framework/Versions/3.7/lib/python3.7/threading.py", line 926, in _bootstrap_inner
    self.run()
  File "/usr/local/Cellar/python/3.7.6_1/Frameworks/Python.framework/Versions/3.7/lib/python3.7/threading.py", line 870, in run
    self._target(*self._args, **self._kwargs)
  File "/Users/vverdeil/workspace/venv/testenv/lib/python3.7/site-packages/IPython/terminal/debugger.py", line 102, in in_thread
    line = self.pt_app.prompt()
  File "/Users/vverdeil/workspace/venv/testenv/lib/python3.7/site-packages/prompt_toolkit/shortcuts/prompt.py", line 986, in prompt
    return self.app.run()
  File "/Users/vverdeil/workspace/venv/testenv/lib/python3.7/site-packages/prompt_toolkit/application/application.py", line 788, in run
    return get_event_loop().run_until_complete(self.run_async(pre_run=pre_run))
  File "/usr/local/Cellar/python/3.7.6_1/Frameworks/Python.framework/Versions/3.7/lib/python3.7/asyncio/events.py", line 644, in get_event_loop
    % threading.current_thread().name)
RuntimeError: There is no current event loop in thread 'Thread-21249'.
```

As you can see I reached thread 21249 before managing to kill the process.

With the same code it works as expected on ipython 7.12, so I guess is it linked to https://github.com/ipython/ipython/pull/12141/

Am I the only one having this bug?


Discussion:
I just discovered that same exact thing today.
I can confirm that this happen to me as well:
```
python=3.6.10
ipython=7.13.0
ipdb=0.12.3
```
My stacktrace:
```
Exception in thread Thread-37891:
Traceback (most recent call last):
  File "/home/myuser/miniconda3/envs/myenv/lib/python3.6/threading.py", line 916, in _bootstrap_inner
    self.run()
  File "/home/myuser/miniconda3/envs/myenv/lib/python3.6/threading.py", line 864, in run
    self._target(*self._args, **self._kwargs)
  File "/home/myuser/miniconda3/envs/myenv/lib/python3.6/site-packages/IPython/terminal/debugger.py", line 102, in in_thread
    line = self.pt_app.prompt()
  File "/home/myuser/miniconda3/envs/myenv/lib/python3.6/site-packages/prompt_toolkit/shortcuts/prompt.py", line 986, in prompt
    return self.app.run()
  File "/home/myuser/miniconda3/envs/myenv/lib/python3.6/site-packages/prompt_toolkit/application/application.py", line 788, in run
    return get_event_loop().run_until_complete(self.run_async(pre_run=pre_run))
  File "/home/myuser/miniconda3/envs/myenv/lib/python3.6/asyncio/events.py", line 694, in get_event_loop
    return get_event_loop_policy().get_event_loop()
  File "/home/myuser/miniconda3/envs/myenv/lib/python3.6/asyncio/events.py", line 602, in get_event_loop
    % threading.current_thread().name)
RuntimeError: There is no current event loop in thread 'Thread-37891'.
```
I believe this is an issue in `7.13`. I was able to resolve this by downgrading to iPython `7.10.2` 
Any news on this? I tried python 7.17.0 and I still have the same issue...
Tried with python 7.19.0 and I still have the issue, any news?
While trying to provide a simple script to reproduce I found out a fix: I had the the issue in an environment with prompt-toolkit==3.0.2 and it is resolve by prompt-toolkit==3.0.8.
Yeah i still into the same issue. Welcome back to pre ipdb times ;(

```
ipdb> request
Exception in thread Thread-2:
Traceback (most recent call last):
  File "/usr/lib/python3.8/threading.py", line 932, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.8/threading.py", line 870, in run
    self._target(*self._args, **self._kwargs)
  File "/home/ubuntu/html/env/lib/python3.8/site-packages/IPython/terminal/debugger.py", line 122, in in_thread
    line = self.pt_app.prompt()
  File "/home/ubuntu/html/env/lib/python3.8/site-packages/prompt_toolkit/shortcuts/prompt.py", line 1013, in prompt
    return self.app.run(set_exception_handler=set_exception_handler)
  File "/home/ubuntu/html/env/lib/python3.8/site-packages/prompt_toolkit/application/application.py", line 816, in run
    return loop.run_until_complete(
  File "/usr/lib/python3.8/asyncio/base_events.py", line 616, in run_until_complete
    return future.result()
  File "/home/ubuntu/html/env/lib/python3.8/site-packages/prompt_toolkit/application/application.py", line 783, in run_async
    return await _run_async2()
  File "/home/ubuntu/html/env/lib/python3.8/site-packages/prompt_toolkit/application/application.py", line 771, in _run_async2
    await self.cancel_and_wait_for_background_tasks()
  File "/home/ubuntu/html/env/lib/python3.8/site-packages/prompt_toolkit/application/application.py", line 872, in cancel_and_wait_for_background_tasks
    await task
RuntimeError: Task <Task pending name='Task-7' coro=<Application.run_async() running at /home/ubuntu/html/env/lib/python3.8/site-packages/prompt_toolkit/application/application.py:783> cb=[_run_until_complete_cb() at /usr/lib/python3.8/asyncio/base_events.py:184]> got Future <Task pending name='Task-52' coro=<KeyProcessor._start_timeout.<locals>.wait() running at /home/ubuntu/html/env/lib/python3.8/site-packages/prompt_toolkit/key_binding/key_processor.py:406> wait_for=<Future cancelled>> attached to a different loop
```
versions:
```
prompt-toolkit==3.0.10
ipdb==0.13.4
ipython==7.19.0
```
In the meantime `pdbpp` works.

Resolving patch:
diff --git a/IPython/terminal/debugger.py b/IPython/terminal/debugger.py
--- a/IPython/terminal/debugger.py
+++ b/IPython/terminal/debugger.py
@@ -10,6 +10,7 @@
 
 from pathlib import Path
 from pygments.token import Token
+from prompt_toolkit.application import create_app_session
 from prompt_toolkit.shortcuts.prompt import PromptSession
 from prompt_toolkit.enums import EditingMode
 from prompt_toolkit.formatted_text import PygmentsTokens
@@ -96,6 +97,17 @@ def gen_comp(self, text):
             self.pt_loop = asyncio.new_event_loop()
             self.pt_app = PromptSession(**options)
 
+    def _prompt(self):
+        """
+        In case other prompt_toolkit apps have to run in parallel to this one (e.g. in madbg),
+        create_app_session must be used to prevent mixing up between them. According to the prompt_toolkit docs:
+
+        > If you need multiple applications running at the same time, you have to create a separate
+        > `AppSession` using a `with create_app_session():` block.
+        """
+        with create_app_session():
+            return self.pt_app.prompt()
+
     def cmdloop(self, intro=None):
         """Repeatedly issue a prompt, accept input, parse an initial prefix
         off the received input, and dispatch to action methods, passing them
@@ -129,9 +141,7 @@ def cmdloop(self, intro=None):
                     # Run the prompt in a different thread.
                     if not _use_simple_prompt:
                         try:
-                            line = self.thread_executor.submit(
-                                self.pt_app.prompt
-                            ).result()
+                            line = self.thread_executor.submit(self._prompt).result()
                         except EOFError:
                             line = "EOF"
                     else:


Test patch: