Run the REPL loop, but run the blocking parts in an executor, so that we don't block the event loop. Both the input and output (which can display a pager) will run in a separate thread with their own event loop, this way ptpython's own event loop won't interfere with
(self)
| 243 | self._handle_keyboard_interrupt(e) |
| 244 | |
| 245 | async def run_async(self) -> None: |
| 246 | """ |
| 247 | Run the REPL loop, but run the blocking parts in an executor, so that |
| 248 | we don't block the event loop. Both the input and output (which can |
| 249 | display a pager) will run in a separate thread with their own event |
| 250 | loop, this way ptpython's own event loop won't interfere with the |
| 251 | asyncio event loop from where this is called. |
| 252 | |
| 253 | The "eval" however happens in the current thread, which is important. |
| 254 | (Both for control-C to work, as well as for the code to see the right |
| 255 | thread in which it was embedded). |
| 256 | """ |
| 257 | loop = asyncio.get_running_loop() |
| 258 | |
| 259 | if self.terminal_title: |
| 260 | set_title(self.terminal_title) |
| 261 | |
| 262 | self._add_to_namespace() |
| 263 | |
| 264 | try: |
| 265 | while True: |
| 266 | try: |
| 267 | # Read. |
| 268 | try: |
| 269 | text = await loop.run_in_executor(None, self.read) |
| 270 | except EOFError: |
| 271 | return |
| 272 | except BaseException: |
| 273 | # Something went wrong while reading input. |
| 274 | # (E.g., a bug in the completer that propagates. Don't |
| 275 | # crash the REPL.) |
| 276 | traceback.print_exc() |
| 277 | continue |
| 278 | |
| 279 | # Eval. |
| 280 | await self.run_and_show_expression_async(text) |
| 281 | |
| 282 | except KeyboardInterrupt as e: |
| 283 | # XXX: This does not yet work properly. In some situations, |
| 284 | # `KeyboardInterrupt` exceptions can end up in the event |
| 285 | # loop selector. |
| 286 | self._handle_keyboard_interrupt(e) |
| 287 | except SystemExit: |
| 288 | return |
| 289 | finally: |
| 290 | if self.terminal_title: |
| 291 | clear_title() |
| 292 | self._remove_from_namespace() |
| 293 | |
| 294 | def eval(self, line: str) -> object: |
| 295 | """ |
no test coverage detected