[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