You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
input() uses sys.__stdout__ instead of sys.stdout for prompt #68590
On Python 3.4, input() does not use wrapped sys.stdout. For example, the following script should print "Wrapped stdout" by print() and input() because sys.stdout is replaced with Writer object.
But the script does not print "Wrapped stdout" as prompt of input(). The script
prints the following.
-----
Wrapped stdout
input
----
Although, when sys.stdin is also wrapped, input() will use sys.stdout for prompt. For example, the following script prints "Wrapped stdout" by print() and input().
This looks like an oversight. In the implementation in bltinmodule.c, if checking sys.stdout.fileno() fails, it clears the error without setting tty = 0. It's the same in 3.5.
/* We should only use (GNU) readline if Python's sys.stdin and sys.stdout are the same as C's stdin and stdout, because we need to pass it those. */tmp=_PyObject_CallMethodId(fin, &PyId_fileno, "");
if (tmp==NULL) {
PyErr_Clear();
tty=0;
}
else {
fd=PyLong_AsLong(tmp);
Py_DECREF(tmp);
if (fd<0&&PyErr_Occurred())
returnNULL;
tty=fd==fileno(stdin) &&isatty(fd);
}
if (tty) {
tmp=_PyObject_CallMethodId(fout, &PyId_fileno, "");
if (tmp==NULL)
PyErr_Clear();
else {
fd=PyLong_AsLong(tmp);
Py_DECREF(tmp);
if (fd<0&&PyErr_Occurred())
returnNULL;
tty=fd==fileno(stdout) &&isatty(fd);
}
}
Okay, so the change is straightforward. With this change the entire test suite passes on my machine.
We'll need a test for this for the test suite, and that's far less straightforward. It seems that test.test_builtin.BuiltinTest.check_input_tty() could be a starting point. Could someone come up with a working test for this?
This patch includes a test case using pty.fork() to ensure stdin is a terminal, so the bug would be triggered. It is a bit tricky, but hopefully works on Unix platforms. I have only tested it on Linux.
Okay I plan to commit a modified version where I moved the input() test methods that use pseudo terminals to a new PtyTests class. The test_input() method stays in the original class, because it shares a helper method with other tests.
I am resisting dropping that decode() step, because it makes any error message from the forked child hard to read:
AssertionError: 256 != 0 : b'quux\r\nTraceback (most recent call last):\r\n File "/media/disk/home/proj/python/cpython/Lib/test/test_builtin.py", line 1593, in test_input_no_stdout_fileno\r\n input("prompt")\r\nTypeError: bad argument type for built-in operation\r\n'
[390/390] test_builtin
Timeout (1:00:00)!
Thread 0x0000000801407400 (most recent call first):
File "/usr/home/buildbot/python/3.4.koobs-freebsd9/build/Lib/test/test_builtin.py", line 1585 in test_input_no_stdout_fileno
File "/usr/home/buildbot/python/3.4.koobs-freebsd9/build/Lib/unittest/case.py", line 580 in run
File "/usr/home/buildbot/python/3.4.koobs-freebsd9/build/Lib/unittest/case.py", line 628 in __call__
I wrote this on Arch Linux, so I doubt your Ubuntu failure is valid. The error you see is what I would expect if the bug were not actually fixed. I suspect you need to recompile /Python/bltinmodule.c, which contains the bug fix.
However, the test also hangs OS X buildbots. I can only guess at why it is hanging, either at the waitpid() line or the os.read() line. I am looking at refactoring my test to use the existing check_input_tty() infrastructure. It seems over the top by adding a separate pipe back to the parent process, but presumably will workaround whatever is causing the hang.
Activity
KeitaKita commentedon Jun 7, 2015
On Python 3.4, input() does not use wrapped sys.stdout. For example, the following script should print "Wrapped stdout" by print() and input() because sys.stdout is replaced with Writer object.
--------
But the script does not print "Wrapped stdout" as prompt of input(). The script
prints the following.
-----
Wrapped stdout
input
----
Although, when sys.stdin is also wrapped, input() will use sys.stdout for prompt. For example, the following script prints "Wrapped stdout" by print() and input().
----
The script prints the following.
-----
Wrapped stdout
Wrapped stdout
----
eryksun commentedon Jun 7, 2015
This looks like an oversight. In the implementation in bltinmodule.c, if checking sys.stdout.fileno() fails, it clears the error without setting tty = 0. It's the same in 3.5.
taleinat commentedon Jun 12, 2015
Okay, so the change is straightforward. With this change the entire test suite passes on my machine.
We'll need a test for this for the test suite, and that's far less straightforward. It seems that test.test_builtin.BuiltinTest.check_input_tty() could be a starting point. Could someone come up with a working test for this?
taleinat commentedon Jun 12, 2015
Here's a patch with just the required fix (no tests).
vadmium commentedon Oct 6, 2015
Patch itself looks good.
vadmium commentedon Oct 7, 2015
This patch includes a test case using pty.fork() to ensure stdin is a terminal, so the bug would be triggered. It is a bit tricky, but hopefully works on Unix platforms. I have only tested it on Linux.
serhiy-storchaka commentedon Oct 7, 2015
LGTM. See also minor note on Rietveld.
I think it is worth to extract all input() tests to separate class.
vadmium commentedon Oct 10, 2015
Okay I plan to commit a modified version where I moved the input() test methods that use pseudo terminals to a new PtyTests class. The test_input() method stays in the original class, because it shares a helper method with other tests.
I am resisting dropping that decode() step, because it makes any error message from the forked child hard to read:
python-dev commentedon Oct 10, 2015
New changeset 425d81d10b13 by Martin Panter in branch '3.4':
Issue bpo-24402: Fix input() when stdout.fileno() fails; diagnosed by Eryksun
https://hg.python.org/cpython/rev/425d81d10b13
New changeset e97d940a6543 by Martin Panter in branch '3.5':
Issue bpo-24402: Merge input() fix from 3.4 into 3.5
https://hg.python.org/cpython/rev/e97d940a6543
New changeset bcc0f8eb6797 by Martin Panter in branch 'default':
Issue bpo-24402: Merge input() fix from 3.5
https://hg.python.org/cpython/rev/bcc0f8eb6797
vadmium commentedon Oct 10, 2015
Seems my test hangs the Free BSD 9 buildbot, although Free BSD 10 apparently passed.
http://buildbot.python.org/all/builders/AMD64%20FreeBSD%209.x%203.4/builds/1128/steps/test/logs/stdio
[390/390] test_builtin
Timeout (1:00:00)!
Thread 0x0000000801407400 (most recent call first):
File "/usr/home/buildbot/python/3.4.koobs-freebsd9/build/Lib/test/test_builtin.py", line 1585 in test_input_no_stdout_fileno
File "/usr/home/buildbot/python/3.4.koobs-freebsd9/build/Lib/unittest/case.py", line 580 in run
File "/usr/home/buildbot/python/3.4.koobs-freebsd9/build/Lib/unittest/case.py", line 628 in __call__
zhangyangyu commentedon Oct 10, 2015
This test also fails on Ubuntu.
1 test failed:
test_builtin
vadmium commentedon Oct 10, 2015
I wrote this on Arch Linux, so I doubt your Ubuntu failure is valid. The error you see is what I would expect if the bug were not actually fixed. I suspect you need to recompile /Python/bltinmodule.c, which contains the bug fix.
However, the test also hangs OS X buildbots. I can only guess at why it is hanging, either at the waitpid() line or the os.read() line. I am looking at refactoring my test to use the existing check_input_tty() infrastructure. It seems over the top by adding a separate pipe back to the parent process, but presumably will workaround whatever is causing the hang.
zhangyangyu commentedon Oct 10, 2015
It's my fault. I forget to recompile. Now it works.
python-dev commentedon Oct 10, 2015
New changeset d8dd9015b086 by Martin Panter in branch '3.4':
Issue bpo-24402: Factor out PtyTests.run_child() in input() tests
https://hg.python.org/cpython/rev/d8dd9015b086
New changeset 6a8f96b46dce by Martin Panter in branch '3.5':
Issue bpo-24402: Merge potential test fix from 3.4 into 3.5
https://hg.python.org/cpython/rev/6a8f96b46dce
New changeset cb574ee7231e by Martin Panter in branch 'default':
Issue bpo-24402: Merge potential test fix from 3.5
https://hg.python.org/cpython/rev/cb574ee7231e
vadmium commentedon Oct 10, 2015
My second attempt seems to have avoided the hang.
For the record, the backtrace from 3.4.koobs-freebsd9 did say it was hanging at the os.waitpid() line, but I still don’t understand why.