[pypy-svn] r55363 - in pypy/dist/pypy: module/_file module/sys rlib translator/goal/test2
arigo at codespeak.net
arigo at codespeak.net
Wed May 28 19:21:13 CEST 2008
Author: arigo
Date: Wed May 28 19:21:11 2008
New Revision: 55363
Modified:
pypy/dist/pypy/module/_file/interp_file.py
pypy/dist/pypy/module/sys/state.py
pypy/dist/pypy/rlib/streamio.py
pypy/dist/pypy/translator/goal/test2/test_app_main.py
Log:
issue372 in-progress
This should ensure that reading from stdin always
flushes stdout first.
Modified: pypy/dist/pypy/module/_file/interp_file.py
==============================================================================
--- pypy/dist/pypy/module/_file/interp_file.py (original)
+++ pypy/dist/pypy/module/_file/interp_file.py Wed May 28 19:21:11 2008
@@ -63,6 +63,16 @@
space.wrap('I/O operation on closed file'))
return stream
+ def _when_reading_first_flush(self, otherfile):
+ """Flush otherfile before reading from self."""
+ self.stream = streamio.CallbackReadFilter(self.stream,
+ otherfile._try_to_flush)
+
+ def _try_to_flush(self):
+ stream = self.stream
+ if stream is not None:
+ stream.flush()
+
# ____________________________________________________________
#
# The 'direct_' methods assume that the caller already acquired the
Modified: pypy/dist/pypy/module/sys/state.py
==============================================================================
--- pypy/dist/pypy/module/sys/state.py (original)
+++ pypy/dist/pypy/module/sys/state.py Wed May 28 19:21:11 2008
@@ -94,6 +94,8 @@
stderr.name = '<stderr>'
self.w_stderr = space.wrap(stderr)
+ stdin._when_reading_first_flush(stdout)
+
def getio(space):
return space.fromcache(IOState)
Modified: pypy/dist/pypy/rlib/streamio.py
==============================================================================
--- pypy/dist/pypy/rlib/streamio.py (original)
+++ pypy/dist/pypy/rlib/streamio.py Wed May 28 19:21:11 2008
@@ -944,6 +944,32 @@
flush_buffers=False)
+class CallbackReadFilter(Stream):
+ """Pseudo read filter that invokes a callback before blocking on a read.
+ """
+
+ def __init__(self, base, callback):
+ self.base = base
+ self.callback = callback
+
+ def flush_buffers(self):
+ self.callback()
+
+ tell = PassThrough("tell", flush_buffers=False)
+ seek = PassThrough("seek", flush_buffers=False)
+ read = PassThrough("read", flush_buffers=True)
+ readall = PassThrough("readall", flush_buffers=True)
+ readline = PassThrough("readline", flush_buffers=True)
+ peek = PassThrough("peek", flush_buffers=False)
+ flush = PassThrough("flush", flush_buffers=False)
+ flushable = PassThrough("flushable", flush_buffers=False)
+ close = PassThrough("close", flush_buffers=False)
+ write = PassThrough("write", flush_buffers=False)
+ truncate = PassThrough("truncate", flush_buffers=False)
+ getnewlines= PassThrough("getnewlines",flush_buffers=False)
+ try_to_find_file_descriptor = PassThrough("try_to_find_file_descriptor",
+ flush_buffers=False)
+
# _________________________________________________
# The following functions are _not_ RPython!
Modified: pypy/dist/pypy/translator/goal/test2/test_app_main.py
==============================================================================
--- pypy/dist/pypy/translator/goal/test2/test_app_main.py (original)
+++ pypy/dist/pypy/translator/goal/test2/test_app_main.py Wed May 28 19:21:11 2008
@@ -312,6 +312,22 @@
finally:
os.environ['PYTHONINSPECT'] = old
+ def test_stdout_flushes_before_stdin_blocks(self):
+ # This doesn't really test app_main.py, but a behavior that
+ # can only be checked on top of py.py with pexpect.
+ path = getscript("""
+ import sys
+ sys.stdout.write('Are you suggesting coconuts migrate? ')
+ line = sys.stdin.readline()
+ assert line.rstrip() == 'Not at all. They could be carried.'
+ print 'A five ounce bird could not carry a one pound coconut.'
+ """)
+ py_py = os.path.join(autopath.pypydir, 'bin', 'py.py')
+ child = self._spawn(sys.executable, [py_py, path])
+ child.expect('Are you suggesting coconuts migrate?', timeout=120)
+ child.sendline('Not at all. They could be carried.')
+ child.expect('A five ounce bird could not carry a one pound coconut.')
+
class TestNonInteractive:
More information about the Pypy-commit
mailing list