[pypy-issue] Issue #1910: fdopen of pty doesn't match cpython behavior (pypy/pypy)
Buck Evan
issues-reply at bitbucket.org
Wed Oct 29 19:11:13 CET 2014
New issue 1910: fdopen of pty doesn't match cpython behavior
https://bitbucket.org/pypy/pypy/issue/1910/fdopen-of-pty-doesnt-match-cpython
Buck Evan:
This is quite similar issue to issue #956, but my script doesn't fail on cpython:
```
$ python2.6 scratch.py
pipe works
pty works
$ python3.4 scratch.py
pipe works
pty works
$ pypy scratch.py
pipe works
Traceback (most recent call last):
File "app_main.py", line 51, in run_toplevel
File "scratch.py", line 55, in <module>
exit(main())
File "scratch.py", line 51, in main
print(test_pty())
File "scratch.py", line 31, in test_pty
out = pipe_output(read, write)
File "scratch.py", line 23, in pipe_output
return fdopen(read).read().replace('\r\n', '\n')
IOError: [Errno 5] Input/output error: '<fdopen>'
$ pypy3 scratch.py
pipe works
Traceback (most recent call last):
File "scratch.py", line 55, in <module>
exit(main())
File "scratch.py", line 51, in main
print(test_pty())
File "scratch.py", line 31, in test_pty
out = pipe_output(read, write)
File "scratch.py", line 23, in pipe_output
return fdopen(read).read().replace('\r\n', '\n')
IOError: [Errno 5] Input/output error
```
Reproduction script:
```
#!python
from __future__ import print_function
from __future__ import unicode_literals
def pipe_output(read, write):
from os import fork, close
from subprocess import Popen
if fork(): #parent
close(write)
else:
close(read)
Popen(
('echo', 'hi', 'there!'),
stdout=write,
close_fds=True,
universal_newlines=True,
)
close(write)
exit()
from os import fdopen
return fdopen(read).read().replace('\r\n', '\n')
def test_pty():
from os import openpty
read, write = openpty()
out = pipe_output(read, write)
assert out == 'hi there!\n', repr(out)
return 'pty works'
def test_pipe():
from os import pipe
read, write = pipe()
out = pipe_output(read, write)
assert out == 'hi there!\n', repr(out)
return 'pipe works'
def main():
print(test_pipe())
print(test_pty())
if __name__ == '__main__':
exit(main())
```
If I create my own read-loop, I can force pypy behavior to match, but it's error prone and a huge pain. Replacing `fdopen().read()` with:
```
from os import read as fread
result = []
lastread = None
while lastread != '':
try:
lastread = fread(read, 1025)
except OSError as err:
if err.errno == 5:
break # slave closed
else:
raise
result.append(lastread)
close(read)
return ''.join(result)
```
More information about the pypy-issue
mailing list