From 91607ebc27d9e9cf9fc333e0f2fe3895a04c48e5 2023-01-09 23:37:15
From: Maor Kleinberger <kmaork@gmail.com>
Date: 2023-01-09 23:37:15
Subject: [PATCH] Use prompt_toolkit.application.create_app_session for debugger prompt

Running the debugger prompt in the default prompt_toolkit session causes issues when more than one prompt_toolkit app is running simultaneously. The errors look exactly like those mentioned in #12192. This commit solves this by using the dedicated API from prompt_toolkit.

---

diff --git a/IPython/terminal/debugger.py b/IPython/terminal/debugger.py
index 1859da2..e47f5f4 100644
--- a/IPython/terminal/debugger.py
+++ b/IPython/terminal/debugger.py
@@ -10,6 +10,7 @@ from . import embed
 
 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 @@ class TerminalPdb(Pdb):
             self.pt_loop = asyncio.new_event_loop()
             self.pt_app = PromptSession(**options)
 
+    def _prompt(self):
+        """
+        In case another 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 @@ class TerminalPdb(Pdb):
                     # 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: