From 72e81d7d846a8e306fd8d98e2f15270a8a537620 Mon Sep 17 00:00:00 2001 From: Jiri Podivin Date: Wed, 26 Oct 2022 14:02:07 +0200 Subject: Removing helper functions providing Python < 3.3 compatibility Functions used for deriving terminal width are no longer necessary, as Python 3.3 introduced[0] built in solution. Remaining helper function `utils.terminal_width` received docstring explaining return parameters. Method `_assign_max_widths` of the `TableFormatter` class was refactored to no longer use the `stdout` argument. Uses of the method were adjusted accordingly. Method now also has minimal docstring. Minor adjustment was made to inline comments to more closely reflect functionality of the code. [0]https://docs.python.org/3.8/library/os.html?highlight=get_terminal_size#os.get_terminal_size Signed-off-by: Jiri Podivin Change-Id: I2898f099227e8c97aef6492c60f2f99038aa1357 --- cliff/formatters/table.py | 14 ++++++---- cliff/tests/test_utils.py | 7 +++-- cliff/utils.py | 67 ++++++----------------------------------------- 3 files changed, 20 insertions(+), 68 deletions(-) diff --git a/cliff/formatters/table.py b/cliff/formatters/table.py index df0b087..fb545c4 100644 --- a/cliff/formatters/table.py +++ b/cliff/formatters/table.py @@ -100,7 +100,7 @@ class TableFormatter(base.ListFormatter, base.SingleFormatter): # preference to wrapping columns smaller than 8 characters. min_width = 8 self._assign_max_widths( - stdout, x, int(parsed_args.max_width), min_width, + x, int(parsed_args.max_width), min_width, parsed_args.fit_width) formatted = x.get_string() @@ -125,7 +125,7 @@ class TableFormatter(base.ListFormatter, base.SingleFormatter): # the Field column readable. min_width = 16 self._assign_max_widths( - stdout, x, int(parsed_args.max_width), min_width, + x, int(parsed_args.max_width), min_width, parsed_args.fit_width) formatted = x.get_string() @@ -170,14 +170,18 @@ class TableFormatter(base.ListFormatter, base.SingleFormatter): return shrink_fields, shrink_remaining @staticmethod - def _assign_max_widths(stdout, x, max_width, min_width=0, fit_width=False): + def _assign_max_widths(x, max_width, min_width=0, fit_width=False): + """Set maximum widths for columns of table `x`, + with the last column recieving either leftover columns + or `min_width`, depending on what offers more space. + """ if max_width > 0: term_width = max_width elif not fit_width: # Fitting is disabled return else: - term_width = utils.terminal_width(stdout) + term_width = utils.terminal_width() if not term_width: # not a tty, so do not set any max widths return @@ -204,6 +208,6 @@ class TableFormatter(base.ListFormatter, base.SingleFormatter): x.max_width[field] = max(min_width, shrink_to) shrink_remaining -= shrink_to - # give the last shrinkable column shrink_to plus any remaining + # give the last shrinkable column any remaining shrink or min_width field = shrink_fields[-1] x.max_width[field] = max(min_width, shrink_remaining) diff --git a/cliff/tests/test_utils.py b/cliff/tests/test_utils.py index 3699a75..7650d78 100644 --- a/cliff/tests/test_utils.py +++ b/cliff/tests/test_utils.py @@ -13,7 +13,6 @@ # under the License. import os -import sys from unittest import mock from cliff.tests import base @@ -23,7 +22,7 @@ from cliff import utils class TestTerminalWidth(base.TestBase): def test(self): - width = utils.terminal_width(sys.stdout) + width = utils.terminal_width() # Results are specific to the execution environment, so only assert # that no error is raised. if width is not None: @@ -33,8 +32,8 @@ class TestTerminalWidth(base.TestBase): def test_get_terminal_size(self, mock_os): ts = os.terminal_size((10, 5)) mock_os.get_terminal_size.return_value = ts - width = utils.terminal_width(sys.stdout) + width = utils.terminal_width() self.assertEqual(10, width) mock_os.get_terminal_size.side_effect = OSError() - width = utils.terminal_width(sys.stdout) + width = utils.terminal_width() self.assertIs(None, width) diff --git a/cliff/utils.py b/cliff/utils.py index 50f3ab6..3fa02a6 100644 --- a/cliff/utils.py +++ b/cliff/utils.py @@ -11,10 +11,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -import ctypes import os -import struct -import sys # Each edit operation is assigned different cost, such as: # 'w' means swap operation, the cost is 0; @@ -93,63 +90,15 @@ def damerau_levenshtein(s1, s2, cost): return row1[-1] -def terminal_width(stdout): - if hasattr(os, 'get_terminal_size'): - # python 3.3 onwards has built-in support for getting terminal size - try: - return os.get_terminal_size().columns - except OSError: - return None +def terminal_width(): + """Return terminal width in columns - if sys.platform == 'win32': - return _get_terminal_width_windows(stdout) - else: - return _get_terminal_width_ioctl(stdout) - - -def _get_terminal_width_windows(stdout): - STD_INPUT_HANDLE = -10 - STD_OUTPUT_HANDLE = -11 - STD_ERROR_HANDLE = -12 - - std_to_win_handle = { - sys.stdin: STD_INPUT_HANDLE, - sys.stdout: STD_OUTPUT_HANDLE, - sys.stderr: STD_ERROR_HANDLE} - - std_handle = std_to_win_handle.get(stdout) - if not std_handle: - return None - - handle = ctypes.windll.kernel32.GetStdHandle(std_handle) - csbi = ctypes.create_string_buffer(22) - - res = ctypes.windll.kernel32.GetConsoleScreenBufferInfo(handle, csbi) - if res: - (size_x, size_y, cur_pos_x, cur_pos_y, attr, - left, top, right, bottom, max_size_x, max_size_y) = struct.unpack( - "hhhhHhhhhhh", csbi.raw) - return size_x - - -def _get_terminal_width_ioctl(stdout): - from fcntl import ioctl - import termios + Uses `os.get_terminal_size` function + :returns: terminal width + :rtype: int or None + """ try: - # winsize structure has 4 unsigned short fields - winsize = b'\0' * struct.calcsize('hhhh') - try: - winsize = ioctl(stdout, termios.TIOCGWINSZ, winsize) - except IOError: - return None - except TypeError: - # this is raised in unit tests as stdout is sometimes a StringIO - return None - winsize = struct.unpack('hhhh', winsize) - columns = winsize[1] - if not columns: - return None - return columns - except IOError: + return os.get_terminal_size().columns + except OSError: return None -- cgit v1.2.1