Get socket for urllib2.urlopen return value for HTTP
Question: I'm trying to do asynchronous downloading of files using urllib2 but have no
succeeded in finding out the socket (or its fileno) to wait for new data for
for HTTP requests. Here's what I've already tried.

    
    
    >>> from urllib2 import urlopen
    >>> from select import select
    >>> r = urlopen('http://stackoverflow.com/')
    >>> select([r], [], [])
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/usr/lib/python2.6/socket.py", line 307, in fileno
        return self._sock.fileno()
    AttributeError: HTTPResponse instance has no attribute 'fileno'
    >>> r.fileno()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/usr/lib/python2.6/socket.py", line 307, in fileno
        return self._sock.fileno()
    AttributeError: HTTPResponse instance has no attribute 'fileno'
    >>> r.fp.fileno()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/usr/lib/python2.6/socket.py", line 307, in fileno
        return self._sock.fileno()
    AttributeError: HTTPResponse instance has no attribute 'fileno'
    >>> select([r.fp], [], [])
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/usr/lib/python2.6/socket.py", line 307, in fileno
        return self._sock.fileno()
    AttributeError: HTTPResponse instance has no attribute 'fileno'
    >>> 
    


Answer: See <http://www.velocityreviews.com/forums/t512553-re-urllib2-urlopen-
broken.html>.

> The problem is that urlib2 was changed to wrap an HTTPResponse object in a
> socket._fileobject to get a few more file methods. Except (as reported
> above) HTTPResponse doesn't have a fileno() method, so when _fileobject
> tries to use it, it blows up.

The solution

Adding an appropriate method to HTTPResponse:

    
    
    def fileno(self):
        return self.fp.fileno()
    

Or, alternatively, use `urllib.urlopen` instead of `urrlib2.urlopen`.

There is a [bug report](http://bugs.python.org/issue1327971) for this issue;
it was fixed in Python 3 and in Python 2.7.

