##// END OF EJS Templates
Don't nest asyncio input hooks....
Jonathan Slenders -
Show More
@@ -580,11 +580,22 b' class TerminalInteractiveShell(InteractiveShell):'
580 # For prompt_toolkit 3.0. We have to create an asyncio event loop with
580 # For prompt_toolkit 3.0. We have to create an asyncio event loop with
581 # this inputhook.
581 # this inputhook.
582 if PTK3:
582 if PTK3:
583 if self._inputhook:
583 import asyncio
584 from prompt_toolkit.eventloop import new_eventloop_with_inputhook
584 from prompt_toolkit.eventloop import new_eventloop_with_inputhook
585
586 if gui == 'asyncio':
587 # When we integrate the asyncio event loop, run the UI in the
588 # same event loop as the rest of the code. don't use an actual
589 # input hook. (Asyncio is not made for nesting event loops.)
590 self.pt_loop = asyncio.get_event_loop()
591
592 elif self._inputhook:
593 # If an inputhook was set, create a new asyncio event loop with
594 # this inputhook for the prompt.
585 self.pt_loop = new_eventloop_with_inputhook(self._inputhook)
595 self.pt_loop = new_eventloop_with_inputhook(self._inputhook)
586 else:
596 else:
587 import asyncio
597 # When there's no inputhook, run the prompt in a separate
598 # asyncio event loop.
588 self.pt_loop = asyncio.new_event_loop()
599 self.pt_loop = asyncio.new_event_loop()
589
600
590 # Run !system commands directly, not through pipes, so terminal programs
601 # Run !system commands directly, not through pipes, so terminal programs
@@ -28,6 +28,10 b' prompt_toolkit`s `patch_stdout`)::'
28
28
29 """
29 """
30 import asyncio
30 import asyncio
31 from prompt_toolkit import __version__ as ptk_version
32
33 PTK3 = ptk_version.startswith('3.')
34
31
35
32 # Keep reference to the original asyncio loop, because getting the event loop
36 # Keep reference to the original asyncio loop, because getting the event loop
33 # within the input hook would return the other loop.
37 # within the input hook would return the other loop.
@@ -35,6 +39,19 b' loop = asyncio.get_event_loop()'
35
39
36
40
37 def inputhook(context):
41 def inputhook(context):
42 """
43 Inputhook for asyncio event loop integration.
44 """
45 # For prompt_toolkit 3.0, this input hook literally doesn't do anything.
46 # The event loop integration here is implemented in `interactiveshell.py`
47 # by running the prompt itself in the current asyncio loop. The main reason
48 # for this is that nesting asyncio event loops is unreliable.
49 if PTK3:
50 return
51
52 # For prompt_toolkit 2.0, we can run the current asyncio event loop,
53 # because prompt_toolkit 2.0 uses a different event loop internally.
54
38 def stop():
55 def stop():
39 loop.stop()
56 loop.stop()
40
57
@@ -44,3 +61,4 b' def inputhook(context):'
44 loop.run_forever()
61 loop.run_forever()
45 finally:
62 finally:
46 loop.remove_reader(fileno)
63 loop.remove_reader(fileno)
64
General Comments 0
You need to be logged in to leave comments. Login now