diff --git a/IPython/core/ultratb.py b/IPython/core/ultratb.py index f92568b..8c4a8fc 100644 --- a/IPython/core/ultratb.py +++ b/IPython/core/ultratb.py @@ -124,6 +124,7 @@ from IPython.utils import path as util_path from IPython.utils import py3compat from IPython.utils import ulinecache from IPython.utils.data import uniq_stable +from IPython.utils.terminal import get_terminal_size from logging import info, error import IPython.utils.colorable as colorable @@ -1029,20 +1030,21 @@ class VerboseTB(TBTools): colors = self.Colors # just a shorthand + quicker name lookup colorsnormal = colors.Normal # used a lot exc = '%s%s%s' % (colors.excName, etype, colorsnormal) + width = min(75, get_terminal_size()[0]) if long_version: # Header with the exception type, python version, and date pyver = 'Python ' + sys.version.split()[0] + ': ' + sys.executable date = time.ctime(time.time()) - head = '%s%s%s\n%s%s%s\n%s' % (colors.topline, '-' * 75, colorsnormal, - exc, ' ' * (75 - len(str(etype)) - len(pyver)), - pyver, date.rjust(75) ) + head = '%s%s%s\n%s%s%s\n%s' % (colors.topline, '-' * width, colorsnormal, + exc, ' ' * (width - len(str(etype)) - len(pyver)), + pyver, date.rjust(width) ) head += "\nA problem occurred executing Python code. Here is the sequence of function" \ "\ncalls leading up to the error, with the most recent (innermost) call last." else: # Simplified header head = '%s%s' % (exc, 'Traceback (most recent call last)'. \ - rjust(75 - len(str(etype))) ) + rjust(width - len(str(etype))) ) return head @@ -1155,7 +1157,7 @@ class VerboseTB(TBTools): colors = self.Colors # just a shorthand + quicker name lookup colorsnormal = colors.Normal # used a lot - head = '%s%s%s' % (colors.topline, '-' * 75, colorsnormal) + head = '%s%s%s' % (colors.topline, '-' * min(75, get_terminal_size()[0]), colorsnormal) structured_traceback_parts = [head] if py3compat.PY3: chained_exceptions_tb_offset = 0 diff --git a/IPython/utils/terminal.py b/IPython/utils/terminal.py index ff31045..9e7be2a 100644 --- a/IPython/utils/terminal.py +++ b/IPython/utils/terminal.py @@ -24,6 +24,7 @@ import os import struct import sys import warnings +import backports.shutil_get_terminal_size from . import py3compat @@ -120,37 +121,5 @@ def freeze_term_title(): ignore_termtitle = True -if sys.platform == 'win32': - def get_terminal_size(defaultx=80, defaulty=25): - """Return size of current terminal console. - - This function try to determine actual size of current working - console window and return tuple (sizex, sizey) if success, - or default size (defaultx, defaulty) otherwise. - - Dependencies: ctypes should be installed. - - Author: Alexander Belchenko (e-mail: bialix AT ukr.net) - """ - try: - import ctypes - except ImportError: - return defaultx, defaulty - - h = ctypes.windll.kernel32.GetStdHandle(-11) - csbi = ctypes.create_string_buffer(22) - res = ctypes.windll.kernel32.GetConsoleScreenBufferInfo(h, csbi) - - if res: - (bufx, bufy, curx, cury, wattr, - left, top, right, bottom, maxx, maxy) = struct.unpack( - "hhhhHhhhhhh", csbi.raw) - sizex = right - left + 1 - sizey = bottom - top + 1 - return (sizex, sizey) - else: - return (defaultx, defaulty) -else: - def get_terminal_size(defaultx=80, defaulty=25): - return defaultx, defaulty - +def get_terminal_size(defaultx=80, defaulty=25): + return backports.shutil_get_terminal_size.get_terminal_size((defaultx, defaulty)) diff --git a/setup.py b/setup.py index e3db283..905b2b0 100755 --- a/setup.py +++ b/setup.py @@ -197,6 +197,7 @@ install_requires = [ 'traitlets', 'prompt_toolkit>=0.58', 'pygments', + 'backports.shutil_get_terminal_size', ] # Platform-specific dependencies: