diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2014-01-09 21:13:48 (GMT) |
---|---|---|
committer | Serhiy Storchaka <storchaka@gmail.com> | 2014-01-09 21:13:48 (GMT) |
commit | 9f8621fa7d3562f472b6a16854df51bfb3fdbd5f (patch) | |
tree | 9d858123a00e7b6191bed9748ef1b7bcf90bcdd4 | |
parent | 3b2afbbf88cb8ba93542641f06c474aab13e50e6 (diff) | |
download | cpython-9f8621fa7d3562f472b6a16854df51bfb3fdbd5f.zip cpython-9f8621fa7d3562f472b6a16854df51bfb3fdbd5f.tar.gz cpython-9f8621fa7d3562f472b6a16854df51bfb3fdbd5f.tar.bz2 |
Issue #13107: argparse and optparse no longer raises an exception when output
a help on environment with too small COLUMNS. Based on patch by
Elazar Gershuni.
-rw-r--r-- | Lib/argparse.py | 8 | ||||
-rw-r--r-- | Lib/optparse.py | 7 | ||||
-rw-r--r-- | Lib/test/test_argparse.py | 54 | ||||
-rw-r--r-- | Lib/test/test_optparse.py | 35 | ||||
-rw-r--r-- | Misc/ACKS | 1 | ||||
-rw-r--r-- | Misc/NEWS | 4 |
6 files changed, 103 insertions, 6 deletions
diff --git a/Lib/argparse.py b/Lib/argparse.py index 30bae57..a4009d0 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -168,6 +168,8 @@ class HelpFormatter(object): self._prog = prog self._indent_increment = indent_increment self._max_help_position = max_help_position + self._max_help_position = min(max_help_position, + max(width - 20, indent_increment * 2)) self._width = width self._current_indent = 0 @@ -339,7 +341,7 @@ class HelpFormatter(object): else: line_len = len(indent) - 1 for part in parts: - if line_len + 1 + len(part) > text_width: + if line_len + 1 + len(part) > text_width and line: lines.append(indent + ' '.join(line)) line = [] line_len = len(indent) - 1 @@ -478,7 +480,7 @@ class HelpFormatter(object): def _format_text(self, text): if '%(prog)' in text: text = text % dict(prog=self._prog) - text_width = self._width - self._current_indent + text_width = max(self._width - self._current_indent, 11) indent = ' ' * self._current_indent return self._fill_text(text, text_width, indent) + '\n\n' @@ -486,7 +488,7 @@ class HelpFormatter(object): # determine the required width and the entry label help_position = min(self._action_max_length + 2, self._max_help_position) - help_width = self._width - help_position + help_width = max(self._width - help_position, 11) action_width = help_position - self._current_indent - 2 action_header = self._format_action_invocation(action) diff --git a/Lib/optparse.py b/Lib/optparse.py index 6c3f456..433276d 100644 --- a/Lib/optparse.py +++ b/Lib/optparse.py @@ -204,7 +204,6 @@ class HelpFormatter: short_first): self.parser = None self.indent_increment = indent_increment - self.help_position = self.max_help_position = max_help_position if width is None: try: width = int(os.environ['COLUMNS']) @@ -212,6 +211,8 @@ class HelpFormatter: width = 80 width -= 2 self.width = width + self.help_position = self.max_help_position = \ + min(max_help_position, max(width - 20, indent_increment * 2)) self.current_indent = 0 self.level = 0 self.help_width = None # computed later @@ -256,7 +257,7 @@ class HelpFormatter: Format a paragraph of free-form text for inclusion in the help output at the current indentation level. """ - text_width = self.width - self.current_indent + text_width = max(self.width - self.current_indent, 11) indent = " "*self.current_indent return textwrap.fill(text, text_width, @@ -337,7 +338,7 @@ class HelpFormatter: self.dedent() self.dedent() self.help_position = min(max_len + 2, self.max_help_position) - self.help_width = self.width - self.help_position + self.help_width = max(self.width - self.help_position, 11) def format_option_strings(self, option): """Return a comma-separated list of option strings & metavariables.""" diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index 30fdf4a..a9b47b7 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -2936,6 +2936,60 @@ class TestHelpBiggerOptionals(HelpTestCase): 0.1 ''' +class TestShortColumns(HelpTestCase): + '''Test extremely small number of columns. + + TestCase prevents "COLUMNS" from being too small in the tests themselves, + but we don't want any exceptions thrown in such case. Only ugly representation. + ''' + def setUp(self): + env = test_support.EnvironmentVarGuard() + env.set("COLUMNS", '15') + self.addCleanup(env.__exit__) + + parser_signature = TestHelpBiggerOptionals.parser_signature + argument_signatures = TestHelpBiggerOptionals.argument_signatures + argument_group_signatures = TestHelpBiggerOptionals.argument_group_signatures + usage = '''\ + usage: PROG + [-h] + [-v] + [-x] + [--y Y] + foo + bar + ''' + help = usage + '''\ + + DESCRIPTION + + positional arguments: + foo + FOO HELP + bar + BAR HELP + + optional arguments: + -h, --help + show this + help + message and + exit + -v, --version + show + program's + version + number and + exit + -x + X HELP + --y Y + Y HELP + + EPILOG + ''' + version = TestHelpBiggerOptionals.version + class TestHelpBiggerOptionalGroups(HelpTestCase): """Make sure that argument help aligns when options are longer""" diff --git a/Lib/test/test_optparse.py b/Lib/test/test_optparse.py index d4e5bb9..44927d6 100644 --- a/Lib/test/test_optparse.py +++ b/Lib/test/test_optparse.py @@ -1444,6 +1444,39 @@ Options: -h, --help show this help message and exit """ +_expected_very_help_short_lines = """\ +Usage: bar.py [options] + +Options: + -a APPLE + throw + APPLEs at + basket + -b NUM, --boo=NUM + shout + "boo!" NUM + times (in + order to + frighten + away all + the evil + spirits + that cause + trouble and + mayhem) + --foo=FOO + store FOO + in the foo + list for + later + fooing + -h, --help + show this + help + message and + exit +""" + class TestHelp(BaseTest): def setUp(self): self.parser = self.make_parser(80) @@ -1505,6 +1538,8 @@ class TestHelp(BaseTest): # we look at $COLUMNS. self.parser = self.make_parser(60) self.assertHelpEquals(_expected_help_short_lines) + self.parser = self.make_parser(0) + self.assertHelpEquals(_expected_very_help_short_lines) def test_help_unicode(self): self.parser = InterceptingOptionParser(usage=SUPPRESS_USAGE) @@ -357,6 +357,7 @@ Marius Gedminas Thomas Gellekum Gabriel Genellina Christos Georgiou +Elazar Gershuni Ben Gertzfield Nadim Ghaznavi Dinu Gherman @@ -35,6 +35,10 @@ Core and Builtins Library ------- +- Issue #13107: argparse and optparse no longer raises an exception when output + a help on environment with too small COLUMNS. Based on patch by + Elazar Gershuni. + - Issue #20207: Always disable SSLv2 except when PROTOCOL_SSLv2 is explicitly asked for. |