Created on 2011-03-29 09:26 by palm.kevin, last changed 2014-06-08 03:17 by python-dev. This issue is now closed.
The interactive help-method provided by python crashes when no stdin-stream is available (sys.stdin == None).
Exception:
Traceback (most recent call last):
File "MyScript", line 4, in <module>
File "C:\Python32\lib\site.py", line 457, in __call__
return pydoc.help(*args, **kwds)
File "C:\Python32\lib\pydoc.py", line 1748, in __call__
self.help(request)
File "C:\Python32\lib\pydoc.py", line 1795, in help
else: doc(request, 'Help on %s:', output=self._output)
File "C:\Python32\lib\pydoc.py", line 1537, in doc
pager(render_doc(thing, title, forceload))
File "C:\Python32\lib\pydoc.py", line 1345, in pager
pager = getpager()
File "C:\Python32\lib\pydoc.py", line 1352, in getpager
if not sys.stdin.isatty() or not sys.stdout.isatty():
AttributeError: 'NoneType' object has no attribute 'isatty'
I think that this situation should be handled:
- either by raising a clear error message indicating that help cannot be displayed because Python is executing in a non-interactive mode
- either by simply printing documentation to stdout (like this: "print(sys.__doc__)")
The code fails precisely when checking that sys.stdin is a valid terminal. See the attached patch for a fix. Out of curiosity, why did you set sys.stdin to None?
I embed Python into an existing, external C application. In addition to this I extend Python to access that app from Python. I do never set explicitly set the standard input to NULL. I guess that the external C application does this...
Thanks for reporting this, palm.kevin, and thanks for the patch, amaury.forgeotdarc.
First, just to be explicit here's a short reproducer:
import sys
sys.stdin = None
help(1)
(Note that to get to the isatty check you need to provide an argument and it has to be something that has help, so `help()` and `help("a")` don't exercise this code path)
Also, here is where sys.stdin can be set to None:
http://hg.python.org/cpython/file/dbceba88b96e/Python/pythonrun.c#l1201
The provided patch fixes the above test case; instead of erroring out with the traceback in the original bug report, the plain pager is used and the help message is printed to stdout.
Anyone on the nosy list interested in writing some tests?
added unit test for this behavior with roxane. verified that the updated patch applies cleanly, passes make patch check, and unit tests all pass.
added try finally as suggested by berkerpeksag. make patchcheck still works and all test cases still pass. did not use the test.support.swap_attr context manager because it may inhibit readability for those that are not familiar with it.
removed comments.
Unfortunately, the test doesn't fail without the fix in, probably because the pager() function replaces itself in the module and thus can only be called once. It might make more sense to just directly test the getpager function with sys.stdin = None.
I've updated the unit test and have verified that it does fail when the original patch is not included. I also ran make patchcheck again and re-ran all of the tests. This should be good to go. Thanks for your insights, Benjamin.
New changeset baca52bb5c74 by Benjamin Peterson in branch '3.4': make sure the builtin help function doesn't fail when sys.stdin is not a valid file (closes #11709) http://hg.python.org/cpython/rev/baca52bb5c74 New changeset 1a9c07880a15 by Benjamin Peterson in branch '2.7': make sure the builtin help function doesn't fail when sys.stdin is not a valid file (closes #11709) http://hg.python.org/cpython/rev/1a9c07880a15 New changeset 3bbb8cb45f58 by Benjamin Peterson in branch 'default': merge 3.4 (#11709) http://hg.python.org/cpython/rev/3bbb8cb45f58
nosy:
+ python-dev
messages:
+ msg220014
resolution: fixed
stage: test needed -> resolved
messages: + msg220013
messages: + msg219990
messages: + msg219984
messages: + msg217241
stage: patch review -> test needed
nosy:
+ amaury.forgeotdarc
messages:
+ msg132480
keywords:
+ patch
stage: patch review