Search code examples
pythonpython-3.xipythonread-eval-print-loop

IPython and REPL behave differently when displaying data without the print function


Note that all experiments have been performed on Python3.4.3 and IPython 5.1.0 (for python3).


Consider a function that returns the identity:

def my_func(): 
    return 1

Now, this function is called from a loop inside a REPL session.

for _ in range(3): 
    my_func()

On, IPython, nothing is displayed.

In [96]: for _ in range(3): 
    ...:     my_func()
    ...:     

In [97]: 

But, on the REPL, something is:

>>> for _ in range(3): 
...     my_func()
... 
1
1
1
>>>

Why is there a difference?

Is it because of something IPython does? I've examined the bytecode and in either case, they're identical. So, it has nothing to do with the bytecode generation but rather with how it is interpreted in either case.


Solution

  • For how it works, IPython compiles loops in 'exec' mode instead of 'single', so sys.displayhook is not triggered for expression statements inside a loop. The regular interactive interpreter executes anything you enter in 'single' mode. 'single' mode is the mode where expression statements trigger sys.displayhook.

    For why IPython does this, the regular Python behavior is more annoying than useful. You rarely want to auto-print the values of expression statements in a loop; more frequently, it'll happen by accident and scroll things you're interested in off the screen.

    IPython tries to provide more useful behavior. It's much more intuitive to explicitly print the things you want printed than to explicitly suppress the things you don't want printed.