Issue 882297: socket's makefile file object doesn't work with timeouts. (original) (raw)
Ok, here's what I did:
import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind(('', 9009)) s.listen(5) s.accept()
Now, I opened a second Python interpreter in which I typed this:
import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('localhost', 9009))
In the first interpreter I did this:
s.accept() (<socket._socketobject object at 0x40163e14>, ('127.0.0.1', 33059)) s1 = _[0] s1.settimeout(3) fd = s1.makefile()
Then I tested that the timeout worked correctly. Still in the first interpreter:
fd.readline() Traceback (most recent call last): File "", line 1, in ? File "/usr/local/lib/python2.3/socket.py", line 338, in readline data = self._sock.recv(self._rbufsize) socket.timeout: timed out fd.readline()
Now, while that was blocking, I did this in the second interpreter:
s.send('foo') 3
Which caused this in the first interpreter (as expected, since I didn't send a newline):
Traceback (most recent call last): File "", line 1, in ? File "/usr/local/lib/python2.3/socket.py", line 338, in readline data = self._sock.recv(self._rbufsize) socket.timeout: timed out
fd.readline()
While that was blocking, I did this in the second interpreter:
s.send('bar\n') 4
Finally sending a newline. But lo and behold! In the first interpreter I got this:
fd.readline() 'bar\n'
Alas, my 'foo' has been lost!
Anyway, the documentation does explicitly state that the socket should be in blocking mode, implying that it does no buffering, but it doesn't say anything about timeouts. Ideally, the file object would buffer enough data until the readline could return meaningfully, but failing that, the documentation should probably be updated to mention that timeouts shouldn't be used with readline on the returned file object.