ipdb
ipdb copied to clipboard
Attach ipdb to new TTY after reading stdin
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
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
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 Thanks for the link to your library!