diff --git a/CHANGELOG.md b/CHANGELOG.md index b85424b6..af7c2430 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## 2.5.4 (TBD) +* Bug Fixes + * Fixed `ZeroDivisionError` in `async_alert()` when `shutil.get_terminal_size().columns` + returned 0. + ## 2.5.3 (November 5, 2024) * Enhancements * Changed `CommandSet._cmd` to a read-only property which never returns `None` because it diff --git a/cmd2/cmd2.py b/cmd2/cmd2.py index b839205b..cd3e8bc1 100644 --- a/cmd2/cmd2.py +++ b/cmd2/cmd2.py @@ -5335,9 +5335,12 @@ def async_alert(self, alert_msg: str, new_prompt: Optional[str] = None) -> None: if update_terminal: import shutil + # Prior to Python 3.11 this can return 0, so use a fallback if needed. + terminal_columns = shutil.get_terminal_size().columns or constants.DEFAULT_TERMINAL_WIDTH + # Print a string which replaces the onscreen prompt and input lines with the alert. terminal_str = ansi.async_alert_str( - terminal_columns=shutil.get_terminal_size().columns, + terminal_columns=terminal_columns, prompt=rl_get_display_prompt(), line=readline.get_line_buffer(), cursor_offset=rl_get_point(), diff --git a/cmd2/constants.py b/cmd2/constants.py index 9f29be86..ebac5da9 100644 --- a/cmd2/constants.py +++ b/cmd2/constants.py @@ -57,3 +57,6 @@ # custom attributes added to argparse Namespaces NS_ATTR_SUBCMD_HANDLER = '__subcmd_handler__' + +# For cases prior to Python 3.11 when shutil.get_terminal_size().columns can return 0. +DEFAULT_TERMINAL_WIDTH = 80 diff --git a/cmd2/utils.py b/cmd2/utils.py index f718d5f1..bd4164ab 100644 --- a/cmd2/utils.py +++ b/cmd2/utils.py @@ -874,7 +874,8 @@ def align_text( ) if width is None: - width = shutil.get_terminal_size().columns + # Prior to Python 3.11 this can return 0, so use a fallback if needed. + width = shutil.get_terminal_size().columns or constants.DEFAULT_TERMINAL_WIDTH if width < 1: raise ValueError("width must be at least 1") diff --git a/tests/test_utils.py b/tests/test_utils.py index 030fa304..a173f7f4 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -17,6 +17,7 @@ import cmd2.utils as cu from cmd2 import ( ansi, + constants, ) from cmd2.constants import ( HORIZONTAL_ELLIPSIS, @@ -624,7 +625,9 @@ def test_align_text_term_width(): text = 'foo' fill_char = ' ' - term_width = shutil.get_terminal_size().columns + # Prior to Python 3.11 this can return 0, so use a fallback, so + # use the same fallback that cu.align_text() does if needed. + term_width = shutil.get_terminal_size().columns or constants.DEFAULT_TERMINAL_WIDTH expected_fill = (term_width - ansi.style_aware_wcswidth(text)) * fill_char aligned = cu.align_text(text, cu.TextAlignment.LEFT, fill_char=fill_char)