##// END OF EJS Templates
Don't nest asyncio input hooks....
Jonathan Slenders -
Show More
@@ -580,11 +580,22 b' class TerminalInteractiveShell(InteractiveShell):'
580 580 # For prompt_toolkit 3.0. We have to create an asyncio event loop with
581 581 # this inputhook.
582 582 if PTK3:
583 if self._inputhook:
584 from prompt_toolkit.eventloop import new_eventloop_with_inputhook
583 import asyncio
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 595 self.pt_loop = new_eventloop_with_inputhook(self._inputhook)
586 596 else:
587 import asyncio
597 # When there's no inputhook, run the prompt in a separate
598 # asyncio event loop.
588 599 self.pt_loop = asyncio.new_event_loop()
589 600
590 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 30 import asyncio
31 from prompt_toolkit import __version__ as ptk_version
32
33 PTK3 = ptk_version.startswith('3.')
34
31 35
32 36 # Keep reference to the original asyncio loop, because getting the event loop
33 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 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 55 def stop():
39 56 loop.stop()
40 57
@@ -44,3 +61,4 b' def inputhook(context):'
44 61 loop.run_forever()
45 62 finally:
46 63 loop.remove_reader(fileno)
64
General Comments 0
You need to be logged in to leave comments. Login now