title: Can I get a socket.makefile to have the same read semantics as a regular file?
body: <p>Python file objects have a read method which takes an optional size argument, which is basically the maximum number of bytes to return.  For example:</p>
  
  <pre><code>fname = "message.txt"
  open(fname, "w").write("Hello World!")
  print open(fname).read()   # prints the entire file contents
  print open(fname).read(5)  # print "Hello"
  print open(fname).read(99) # prints "Hello World!"
  </code></pre>
  
  <p>So even though our file has fewer than 99 characters, a call to <code>read(99)</code> returns immediately with all of the available data.</p>
  
  <p>I'd like to get this behavior on the file objects returned from <a href="http://docs.python.org/library/socket.html#socket.socket.makefile" rel="noreferrer">socket.makefile</a>.  But if I say:</p>
  
  <pre><code>import socket
  ADDR = ("localhost", 12345)
  
  listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  listener.bind(ADDR)
  listener.listen(1)
  
  client = socket.create_connection(ADDR)
  cf = client.makefile("r+b", bufsize=0)
  
  server, client_addr = listener.accept()
  sf = server.makefile("r+b", bufsize=0)
  
  sf.write("Hello World!")
  sf.flush()
  print cf.read(99)         # hangs forever
  </code></pre>
  
  <p>According to the <code>socket.makefile</code> docs, <i>"The optional mode and bufsize arguments are interpreted the same way as by the built-in file() function."</i>  But my original file example works even when I say <code>open(fname, "r+b", 0)</code>, whereas I can't figure out a way to return all available data up to the specified number of bytes with a socket pseudo-file.</p>
  
  <p>This seems to work perfectly well if I just use <code>socket.recv</code>:</p>
  
  <pre><code>import socket
  ADDR = ("localhost", 12345)
  
  listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  listener.bind(ADDR)
  listener.listen(1)
  
  client = socket.create_connection(ADDR)
  server, client_addr = listener.accept()
  
  server.sendall("Hello World!")
  print client.recv(99)           # prints "Hello World!"
  </code></pre>
  
  <p>So is there any way to make this work with <code>socket.makefile</code>, or is this kind of "advanced" functionality simply not available?</p>
  
  <p><b>EDIT:</b> Python 3.2 seems to behave correctly, though the argument syntax to <code>socket.makefile</code> appears to have changed:</p>
  
  <pre><code>import socket
  ADDR = ("localhost", 12345)
  
  listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  listener.bind(ADDR)
  listener.listen(1)
  
  client = socket.create_connection(ADDR)
  cf = client.makefile("rwb", buffering=0)
  
  server, client_addr = listener.accept()
  sf = server.makefile("rwb", buffering=0)
  
  sf.write(b"Hello World!")
  sf.flush()
  print(cf.read(99))         # prints "Hello World!"
  </code></pre>
  
  <p>I haven't dug into the source code yet to figure out the difference between these two versions, but that may be a hint.</p>