Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iPython embed() automatically exits when calling script from bash file

I have a data processing pipeline setup that I want to debug. The pipeline consists of a bash script that calls a python script.

I usually use iPython's embed() function for debugging. However, when calling the python script from the bash file, the embed() function is called but immediately exited, without me being able to interfere. When running the same python program directly from the command line I don't observe this kind of behavior. Is this intended behavior or am I doing something wrong?

Python 2.7.6 (default, Oct 26 2016, 20:30:19)
Type "copyright", "credits" or "license" for more information.

IPython 2.4.1 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

In [1]:
Do you really want to exit ([y]/n)?
'follow up code prints here'
like image 648
Dahlai Avatar asked Nov 16 '25 20:11

Dahlai


1 Answers

I can replicate the problem like this:

# test.py
import IPython
import sys
print(sys.stdin.read())
IPython.embed()
# session
❯ echo 'foo' | python test.py
foo

Python 3.6.8 (default, Oct  7 2019, 12:59:55)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.10.1 -- An enhanced Interactive Python. Type '?' for help.

In [1]: Do you really want to exit ([y]/n)?

❯ # I didn't quit on purpose, it happened automatically

STDIN is not a TTY, so I'm thinking that IPython is worried that the inbound text (via the pipe) won't be a user typing. It doesn't want foo (from my example above) to spew into the IPython shell and do something unexpected.

You can work around this by getting your terminal id via the tty command, and redirecting stdin to the calling terminal after it has finished reading from the pipe, something like this:

with open('/dev/pts/16') as user_tty:
    sys.stdin=user_tty
    IPython.embed()

For more on ttys, see this post. Note also that if you put the wrong tty in there, input from some other terminal will control IPython.

I'm not sure if it's possible for IPython to know what the calling tty would have been, had it not been overwritten by bash to be the output-side of the pipe.

Edit: Here's my workaround put more simply: How do I debug a script that uses stdin with ipython?

like image 102
MatrixManAtYrService Avatar answered Nov 19 '25 09:11

MatrixManAtYrService