Signal handler works in python but not in ipython

270 views Asked by At

I'm attempting to set the numpy print options using a signal handler on the window resize event. Don't want to make the connection until numpy has been imported, and don't want to import numpy automatically at python startup. I've got it almost-working with the code below:

# example.py
import wrapt

@wrapt.when_imported('numpy')
def post_import_hook(numpy):
    import signal
    try:
        from shutil import get_terminal_size
    except ImportError:
        # Python 2
        from shutil_backports import get_terminal_size

    def resize_handler(signum=signal.SIGWINCH, frame=None):
        w, h = get_terminal_size()
        numpy.set_printoptions(linewidth=w)
        print('handled window resize {}'.format(w))

    resize_handler()
    signal.signal(signal.SIGWINCH, resize_handler)

It works in vanilla python REPL (test with python -i example.py and resize the terminal a bit). But it doesn't work in ipython when the same code is added to my startup ipython config, and I don't understand why.

I'm not fixed on this particular approach (that's just what I've tried so far), so I'll phrase the question more generally:

How can numpy correctly fill to the terminal width automatically in ipython?

You can use print(np.arange(200)), for example, to check numpy's line wrapping behaviour.

1

There are 1 answers

0
Andras Deak -- Слава Україні On BEST ANSWER

Inspired by the standard fix for printing large arrays without truncation, I tried setting the line width to infinity. This seems to be working fine both in the REPL and in ipython, so I suggest this workaround:

import numpy
numpy.set_printoptions(linewidth=numpy.inf)

This doesn't explain why your fix doesn't work for ipython, but in case the above line doesn't mess with anything unexpected, it should make printing immune to resizing.