ipdb icon indicating copy to clipboard operation
ipdb copied to clipboard

Attach ipdb to new TTY after reading stdin

Open mschwager opened this issue 3 years ago • 3 comments

Hi there,

Thanks so much for creating ipdb, I use it every day.

I'd like to create a Python script that has data piped to it then drops into an ipdb shell. This is tricky because we have to re-purpose stdin during the execution of the script. I was able to successfully read from stdin, then drop into a shell, but the shell is lacking autocompletion, arrow keys, and other readline niceties.

Here's my script:

#!/usr/bin/python3
import sys, ipdb

def main():
    buff = sys.stdin.read()
    print(buff)
    sys.stdin = open('/dev/tty')
    ipdb.set_trace()

if __name__ == "__main__":
    main()

I'm then successfully dropped into a shell with the piped data:

$ echo "FOO" | ipipe.py 
FOO

--Return--
None
> ipipe.py(8)main()
      7     sys.stdin = open('/dev/tty')
----> 8     ipdb.set_trace()
      9 

ipdb> 

But I don't have any ipdb/IPython niceties in the shell. Is there a good way to achieve this?

Here are some resources I was using when trying this out:

  • https://stackoverflow.com/questions/9178751/use-pdb-set-trace-in-a-script-that-reads-stdin-via-a-pipe
  • https://stackoverflow.com/questions/17074177/how-to-debug-python-cli-that-takes-stdin
  • https://unix.stackexchange.com/questions/552569/piping-dev-tty-to-ipython-without-losing-formatting-or-tab-completion

I also tried various IPython capabilities like the following, but I could get those to work either:

#!/usr/bin/python3
import sys, IPython

def main():
    buff = sys.stdin.read()
    print(buff)
    stdin = sys.stdin = open('/dev/tty')
    p = IPython.terminal.debugger.TerminalPdb(stdin=stdin)
    p.set_trace()

if __name__ == "__main__":
    main()
$ echo "FOO" | ipipe.py 
FOO

Traceback (most recent call last):
  File "~/bin/ipipe.py", line 12, in <module>
    main()
  File "~/bin/ipipe.py", line 8, in main
    p = IPython.terminal.debugger.TerminalPdb(stdin=stdin)
  File "~/.local/lib/python3.6/site-packages/IPython/terminal/debugger.py", line 32, in __init__
    self.pt_init()
  File "~/.local/lib/python3.6/site-packages/IPython/terminal/debugger.py", line 65, in pt_init
    style=self.shell.style,
AttributeError: 'TerminalInteractiveShell' object has no attribute 'style'

Which lead me to the following issues, which seem to be similar:

  • https://github.com/ipython/ipython/issues/11745
  • https://github.com/pytest-dev/pytest/issues/2064

mschwager avatar Oct 21 '20 20:10 mschwager

I found this amazing library by @lebedov -- i think this is closely related to what you might be looking for?

https://github.com/lebedov/ripdb/blob/master/ripdb/init.py

richardliaw avatar Dec 04 '20 03:12 richardliaw

Check out https://github.com/kmaork/madbg , a library I made for this exact purpose with some additional features like attaching to a running process and opening a debugger

kmaork avatar Mar 06 '21 10:03 kmaork

@kmaork Thanks for the link to your library!

lebedov avatar Mar 08 '21 13:03 lebedov