homepage

This issue tracker has been migrated to GitHub , and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: argparse print_help() fails if COLUMNS is set to a low value
Type: Stage: resolved
Components: Library (Lib) Versions: Python 3.3, Python 3.4, Python 2.7
process
Status: closed Resolution: duplicate
Dependencies: Superseder: Text width in optparse.py can become negative
View: 13107
Assigned To: Nosy List: Russell.Sim, bethard, georg.brandl, serhiy.storchaka, terry.reedy, zbysz
Priority: normal Keywords: patch

Created on 2012年01月06日 13:55 by zbysz, last changed 2022年04月11日 14:57 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
test_argparse_narrow.py zbysz, 2012年01月06日 13:55 failing testcase
13720.patch bethard, 2012年07月23日 00:17 review
Messages (9)
msg150733 - (view) Author: Zbyszek Jędrzejewski-Szmek (zbysz) * Date: 2012年01月06日 13:55
% cat test_argparse_narrow.py
import argparse
argparse.ArgumentParser().print_help()
% COLUMNS=15 ./python test_argparse_narrow.py
Traceback (most recent call last):
 File "test_argparse_narrow.py", line 2, in <module>
 argparse.ArgumentParser().print_help()
 File "/home/zbyszek/python/cpython/Lib/argparse.py", line 2347, in print_help
 self._print_message(self.format_help(), file)
 File "/home/zbyszek/python/cpython/Lib/argparse.py", line 2321, in format_help
 return formatter.format_help()
 File "/home/zbyszek/python/cpython/Lib/argparse.py", line 276, in format_help
 help = self._root_section.format_help()
 File "/home/zbyszek/python/cpython/Lib/argparse.py", line 206, in format_help
 func(*args)
 File "/home/zbyszek/python/cpython/Lib/argparse.py", line 206, in format_help
 func(*args)
 File "/home/zbyszek/python/cpython/Lib/argparse.py", line 514, in _format_action
 help_lines = self._split_lines(help_text, help_width)
 File "/home/zbyszek/python/cpython/Lib/argparse.py", line 615, in _split_lines
 return _textwrap.wrap(text, width)
 File "/home/zbyszek/python/cpython/Lib/textwrap.py", line 316, in wrap
 return w.wrap(text)
 File "/home/zbyszek/python/cpython/Lib/textwrap.py", line 291, in wrap
 return self._wrap_chunks(chunks)
 File "/home/zbyszek/python/cpython/Lib/textwrap.py", line 220, in _wrap_chunks
 raise ValueError("invalid width %r (must be > 0)" % self.width)
ValueError: invalid width -1 (must be > 0)
argparse should not fail if the user resizes the window to something very thin...
msg150782 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2012年01月07日 00:57
The code works fine on 3.2.2, Win7, IDLE, narrowest window possible (about 14 chars), which actually wraps to the window width. (In command window, lines are fixed length and scroll bar is added if window is narrowed.) What system and version are you running? 
The error directly comes from textwrap. In the other hand, textwrap.wrap works with widths down to 1 (on 3.2.2), which suggests that argparse is calling it wrong. Except that it is not on my system. 
Could you add 'print(width)' before the call to textwrap
 return _textwrap.wrap(text, width)
to see if -1 is being passed?
msg150785 - (view) Author: Zbyszek Jędrzejewski-Szmek (zbysz) * Date: 2012年01月07日 08:50
> What system and version are you running? 
Linux (debian amd64), Python is compiled from hg (1ea8b7233fd7).
> The error directly comes from textwrap. In the other hand, 
> textwrap.wrap works with widths down to 1 (on 3.2.2), which suggests 
> that argparse is calling it wrong. Except that it is not on my system. 
That's really surprising, because it is all pure Python code and don't
really see how it _could_ be right: take $COLUMNS, subtract, subtract,
and sooner or later _width will go below 0.
> Could you add 'print(width)' before the call to textwrap
> return _textwrap.wrap(text, width)
> to see if -1 is being passed?
Prints -1.
> The code works fine on 3.2.2, Win7, IDLE, narrowest window possible (about 14 
> chars), which actually wraps to the window width. 
Oh, I just tried it in IDLE and it prints:
 64
 64
 64
 64
 usage: ...
in a very small window (30 cells wide). So IDLE is just doesn't allow you to
go below a certain size.
See also #13107.
msg150786 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2012年01月07日 09:14
I am not setting columns, so that might be the important difference.
msg150787 - (view) Author: Zbyszek Jędrzejewski-Szmek (zbysz) * Date: 2012年01月07日 09:34
> I am not setting columns, so that might be the important difference.
Yeah, the whole example with IDLE is moot: argparse only checks
$COLUMNS and defaults to 80, so if COLUMNS is not set, you are only
checking if the code works with 80 columns.
Please try my commandline example or set os.environ['COLUMNS'] = 15.
I get the exception in IDLE too.
msg150789 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2012年01月07日 11:38
Now I get error, even with Window actually about 100 columns wide.
msg166102 - (view) Author: Russell Sim (Russell.Sim) Date: 2012年07月22日 03:05
Hi,
I am having the same problem while running ipython in a batch mode emacs. Apparently you can't even start ipython if the columns are less than 27, since they use the argparse library for the magic method help printing and they preformat the strings at import time. So importing the library fails. :(
I have a simple patch that fixes it but from what i can tell if you set the columns to 10 or 1000 there is no effect on the output, so i wonder if it even pays any attention to the width during rendering.
If you think it's of value I am happy to write tests. Or if someone has a better implementation idea I'll be happy to implement it, but if you are on a terminal that is getting <27 characters then you can't really expect the formmating of the messages to be that readable.
--- cpython/Lib/argparse.py	2012年07月22日 12:10:42.751869655 +1000
+++ /tmp/ediff3953qkY	2012年07月22日 12:54:51.380700044 +1000
@@ -95,6 +95,7 @@
 def _callable(obj):
 return hasattr(obj, '__call__') or hasattr(obj, '__bases__')
 
+MIN_WIDTH = 10
 
 SUPPRESS = '==SUPPRESS=='
 
@@ -486,7 +487,10 @@
 # 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
+ if self._width - help_position > MIN_WIDTH:
+ help_width = self._width - help_position
+ else:
+ help_width = MIN_WIDTH
 action_width = help_position - self._current_indent - 2
 action_header = self._format_action_invocation(action)
msg166188 - (view) Author: Steven Bethard (bethard) * (Python committer) Date: 2012年07月23日 00:17
Definitely a bug here. Attached is a patch and a test, based on Russell Sim's suggestion, that should fix it.
msg211408 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2014年02月17日 11:31
Thank you Zbyszek and Steven for your report and patch, but this was fixed in issue13107.
History
Date User Action Args
2022年04月11日 14:57:25adminsetgithub: 57929
2014年02月17日 11:31:19serhiy.storchakasetstatus: open -> closed

superseder: Text width in optparse.py can become negative

nosy: + serhiy.storchaka
messages: + msg211408
resolution: duplicate
stage: resolved
2012年07月23日 00:17:18bethardsetfiles: + 13720.patch
keywords: + patch
messages: + msg166188

versions: + Python 3.4
2012年07月22日 03:05:57Russell.Simsetnosy: + Russell.Sim

messages: + msg166102
versions: + Python 2.7
2012年01月07日 11:38:07terry.reedysetmessages: + msg150789
2012年01月07日 09:34:22zbyszsetmessages: + msg150787
2012年01月07日 09:14:28terry.reedysetmessages: + msg150786
2012年01月07日 08:50:29zbyszsetmessages: + msg150785
2012年01月07日 00:57:30terry.reedysetnosy: + georg.brandl, terry.reedy, bethard
messages: + msg150782
2012年01月06日 13:55:48zbyszcreate

AltStyle によって変換されたページ (->オリジナル) /