[pypy-commit] pypy default: fix the case of nonblocking sys.stdin
fijal
noreply at buildbot.pypy.org
Sat Oct 8 21:06:29 CEST 2011
Author: Maciej Fijalkowski <fijall at gmail.com>
Branch:
Changeset: r47882:3f96afe7cdc2
Date: 2011-10-08 21:06 +0200
http://bitbucket.org/pypy/pypy/changeset/3f96afe7cdc2/
Log: fix the case of nonblocking sys.stdin
diff --git a/pypy/module/_file/test/test_file.py b/pypy/module/_file/test/test_file.py
--- a/pypy/module/_file/test/test_file.py
+++ b/pypy/module/_file/test/test_file.py
@@ -1,5 +1,5 @@
from __future__ import with_statement
-import py
+import py, os, errno
from pypy.conftest import gettestobjspace, option
@@ -257,6 +257,35 @@
assert self.temppath in g.getvalue()
+class AppTestNonblocking(object):
+ def setup_class(cls):
+ from pypy.module._file.interp_file import W_File
+
+ cls.old_read = os.read
+ state = [0]
+ def read(fd, n=None):
+ if fd != 42:
+ return cls.old_read(fd, n)
+ if state[0] == 0:
+ state[0] += 1
+ return "xyz"
+ if state[0] < 3:
+ state[0] += 1
+ raise OSError(errno.EAGAIN, "xyz")
+ return ''
+ os.read = read
+ stdin = W_File(cls.space)
+ stdin.file_fdopen(42, "r", 1)
+ stdin.name = '<stdin>'
+ cls.w_stream = stdin
+
+ def teardown_class(cls):
+ os.read = cls.old_read
+
+ def test_nonblocking_file(self):
+ res = self.stream.read()
+ assert res == 'xyz'
+
class AppTestConcurrency(object):
# these tests only really make sense on top of a translated pypy-c,
# because on top of py.py the inner calls to os.write() don't
diff --git a/pypy/rlib/streamio.py b/pypy/rlib/streamio.py
--- a/pypy/rlib/streamio.py
+++ b/pypy/rlib/streamio.py
@@ -37,7 +37,7 @@
# return value of tell(), but not as argument to read().
#
-import os, sys
+import os, sys, errno
from pypy.rlib.objectmodel import specialize, we_are_translated
from pypy.rlib.rarithmetic import r_longlong, intmask
from pypy.rlib import rposix
@@ -587,12 +587,22 @@
def readall(self):
pos = self.pos
assert pos >= 0
- chunks = [self.buf[pos:]]
+ if self.buf:
+ chunks = [self.buf[pos:]]
+ else:
+ chunks = []
self.buf = ""
self.pos = 0
bufsize = self.bufsize
while 1:
- data = self.do_read(bufsize)
+ try:
+ data = self.do_read(bufsize)
+ except OSError, o:
+ if o.errno != errno.EAGAIN:
+ raise
+ if not chunks:
+ raise
+ break
if not data:
break
chunks.append(data)
More information about the pypy-commit
mailing list