[Patches] httplib.HTTP.connect raises wrong exception

Skip Montanaro skip@mojam.com (Skip Montanaro)
Tue, 28 Mar 2000 08:36:57 -0600 (CST)


    Guido> Hm...  it seems that there should be an architecture for
    Guido> providing alternatives to the socket module.  I've never even
    Guido> heard of the timeout_socket module...

When the Vaults of Parnassus are back online, check there.  The
timeout_socket module, as its name implies, allows you to specify timeouts
for sockets.  I find it quite useful for my Gig Gopher (software that peeks
at a few thousand registered sites on a regular basis looking for new
concert dates).

    Guido> Hacking httplib seems the wrong place to approach this.  What are
    Guido> the requirements?

I don't really hack httplib, just subclass httplib.HTTP and override the
connect method.  Here's all I did (minus the docstring):

    class HTTP(httplib.HTTP):
	def connect(self, host, port = 0):
	    if not port:
		i = string.find(host, ':')
		if i >= 0:
		    host, port = host[:i], host[i+1:]
		    try: port = string.atoi(port)
		    except string.atoi_error:
			raise ValueError, "nonnumeric port"
	    if not port: port = httplib.HTTP_PORT
	    self.sock = timeout_socket.timeout_socket(timeout=60)
	    if self.debuglevel > 0: print 'connect:', (host, port)
	    self.sock.connect(host, port)

I suppose I should have added a timeout parameter to connect().

Timeout_socket.py isn't very big.  It's ideas could probably be incorporated
directly into the socket module without too much effort.

(Taking things a bit further afield, the one that's really nasty to subclass
is urllib.URLopener - subclassing it to use the above version of HTTP.
That's where some rearchitecting would be useful.  You need to paste 50+
lines from the open_http method to make the one-line change to replace
httplib.HTTP with the subclass because the open_http method explicitly calls
for httplib.HTTP.  That's a fair bit of coupling between the original and
the subclass. Overriding the open_ftp method would be similarly painful.)

    [ ... snip stuff about:
      * ValueError
      * example of similar history with the os module
      * proposed one-line change to httplib
      ... ]

    Guido> And all this because you believe that raising some other module's
    Guido> error is a sin?  I don't have a problem with such behavior --
    Guido> what's the reason?

Well, let's see:

    1. that httplib can raise socket.error is not documented.  (this can, of 
       course, be remedied.)
    2. what about the situation where we rearchitect things to allow easy
       use of alternatives to the socket module?
    3. it's not even an exception raised by the socket module that's getting 
       passed on to the user.

My main problem is that it's a misrepresentation of the facts.  I'd worry
less if it was actually an exception raised by the socket module that was
either passing through httplib or being reraised by it.

Do what you like.  If you decide to make a change, note that smtplib also
suffers from the same problem.

Skip