mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +00:00 
			
		
		
		
	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.
This commit is contained in:
		
							parent
							
								
									32c4915b23
								
							
						
					
					
						commit
						f451112413
					
				
					 6 changed files with 103 additions and 6 deletions
				
			
		|  | @ -165,6 +165,8 @@ def __init__(self, | |||
|         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 | ||||
|  | @ -336,7 +338,7 @@ def get_lines(parts, indent, prefix=None): | |||
|                     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 | ||||
|  | @ -476,7 +478,7 @@ def _format_actions_usage(self, actions, groups): | |||
|     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' | ||||
| 
 | ||||
|  | @ -484,7 +486,7 @@ def _format_action(self, action): | |||
|         # 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) | ||||
| 
 | ||||
|  |  | |||
|  | @ -209,7 +209,6 @@ def __init__(self, | |||
|                  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']) | ||||
|  | @ -217,6 +216,8 @@ def __init__(self, | |||
|                 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 | ||||
|  | @ -261,7 +262,7 @@ def _format_text(self, text): | |||
|         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, | ||||
|  | @ -342,7 +343,7 @@ def store_option_strings(self, parser): | |||
|         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.""" | ||||
|  |  | |||
|  | @ -2973,6 +2973,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 = 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""" | ||||
|  |  | |||
|  | @ -1443,6 +1443,39 @@ def test_conflict_override_args(self): | |||
|   -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) | ||||
|  | @ -1500,6 +1533,8 @@ def test_wrap_columns(self): | |||
|         # 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) | ||||
|  |  | |||
|  | @ -430,6 +430,7 @@ Marius Gedminas | |||
| Thomas Gellekum | ||||
| Gabriel Genellina | ||||
| Christos Georgiou | ||||
| Elazar Gershuni | ||||
| Ben Gertzfield | ||||
| Nadim Ghaznavi | ||||
| Dinu Gherman | ||||
|  |  | |||
|  | @ -43,6 +43,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. | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Serhiy Storchaka
						Serhiy Storchaka