title: Python3 asyncio: wait_for() communicate() with timeout, how to get partial result?
body: <p><a href="https://docs.python.org/3/library/asyncio-subprocess.html#asyncio.asyncio.subprocess.Process" rel="noreferrer">The Python docs about asyncio - Subprocess say:</a></p>
  
  <blockquote>
    <p>The <code>communicate()</code> and <code>wait()</code> methods don’t take a timeout parameter: use the <code>wait_for()</code> function</p>
  </blockquote>
  
  <p>It's pretty easy to impose a timeout on <code>communicate()</code> using <code>wait_for()</code>, however I can't find a way to retrieve the partial results from the interrupted <code>communicate()</code> call, and subsequent calls to <code>communicate()</code> doesn't return the lost part either.</p>
  
  <p>Example script:</p>
  
  <pre><code>#! /usr/bin/env python3
  
  import asyncio
  
  async def communicate_short(loop):
      p = await asyncio.create_subprocess_exec('ping', '127.0.0.1', '-n', '4', stdout=asyncio.subprocess.PIPE)
      # For Linux: use '-c' instead of '-n'
  
      try:
          # 2 seconds timeout
          res = await asyncio.wait_for(p.communicate(), 2)
      except asyncio.TimeoutError as e:
          # After timeout happens:
          # How do I get the subprocess's STDOUT up to this point?
          try:
              print(res[0].decode('utf-8'))
              # Will raise NameError since the communicate() call did not complete
          except NameError as e:
              print('NameError: %s' % e)
  
  
      res = await p.communicate()
      print(res[0].decode('utf-8'))
      # Only prints the later half of ping's STDOUT
  
  if __name__ == '__main__':
      loop = asyncio.ProactorEventLoop()
      asyncio.set_event_loop(loop)
      # For Linux: just do loop = asyncio.get_event_loop()
  
      loop.run_until_complete(communicate_short(loop))
  </code></pre>
  
  <p>Output from the example script:</p>
  
  <pre><code>NameError: local variable 'res' referenced before assignment
  Reply from 127.0.0.1: bytes=32 time&lt;1ms TTL=128
  Reply from 127.0.0.1: bytes=32 time&lt;1ms TTL=128
  
  Ping statistics for 127.0.0.1:
      Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
  Approximate round trip times in milli-seconds:
      Minimum = 0ms, Maximum = 0ms, Average = 0ms
  </code></pre>
  
  <p>Notice that only the last 2 packets are printed. Output about the first 2 packets are lost.</p>
  
  <p>So, how should I get the output from the subprocess before the timeout happened?</p>
  
  <p><strong>Edit</strong>: To be more precise, ideally what I'm looking for something that:</p>
  
  <ol>
  <li><p>Does what <code>communicate()</code> does, i.e. asynchronously write to a subprocess's STDIN and read its STDOUT and STDERR, without possibility of deadlocking (<a href="https://docs.python.org/3/library/asyncio-subprocess.html#asyncio.asyncio.subprocess.Process.stderr" rel="noreferrer">that the docs ominously warn about</a>);</p></li>
  <li><p>has a configurable total timeout, so that when either the subprocess terminates or the timeout is reached, the received STDOUT and STDERR so far are returned.</p></li>
  </ol>
  
  <p>Looks like such a thing does not exist yet, and one would have to implement it.</p>