prompt-toolkit / ptpython

A better Python REPL
BSD 3-Clause "New" or "Revised" License
5.19k stars 277 forks source link

ptpython's IPython embed doesn't work within GDB #546

Open depau opened 1 year ago

depau commented 1 year ago

I'm trying to use PtPython with IPython inside the GDB integrated python console.

I wrote this GDB command to bring up a PtPython REPL within GDB:

ptpython_cmd.py

import sys

import gdb
from ptpython.ipython import embed

class PtPythonCommand(gdb.Command):
    def __init__(self) -> None:
        super().__init__("ptpython", gdb.COMMAND_USER)

    def invoke(self, arg: str, from_tty: bool):
        self.dont_repeat()

        if not from_tty:
            raise Exception("PtPython can only be launched from the TTY")

        stdout = sys.stdout
        stderr = sys.stderr
        stdin = sys.stdin

        try:
            sys.stdout = sys.__stdout__
            sys.stderr = sys.__stderr__
            sys.stdin = sys.__stdin__

            embed()

        except SystemExit as e:
            if e.code != 0:
                print("ptpython exited with code", e.code)

        finally:
            sys.stdout = stdout
            sys.stderr = stderr
            sys.stdin = stdin

PtPythonCommand()

Run gdb -ex "source ptpython_cmd.py" -ex ptpython to load the script and launch the custom command.

The shell is very broken and it doesn't display the TUI. However, if I use the regular PtPython embed, it works great (replace the embed import with from ptpython import embed to reproduce that).

I suppose there could be something wrong with the IPython embed. I'm not aware of any differences in the GDB python interpreter vs regular Python, but I suspect they might be messing with the asyncio event loop. I haven't found proof of this, though.