Work around Python 2.7 failure to initialize base class

urllib2 returns a malformed HTTPError object in certain situations.
For example, urllib2 has a couple of places where it creates an
HTTPError object with no fp:

  if self.retried > 5:
    # retry sending the username:password 5 times before failing.
    raise HTTPError(req.get_full_url(), 401, "basic auth failed",
                    headers, None)

When it does that, HTTPError's ctor doesn't call through to
addinfourl's ctor:

  # The addinfourl classes depend on fp being a valid file
  # object.  In some cases, the HTTPError may not have a valid
  # file object.  If this happens, the simplest workaround is to
  # not initialize the base classes.
  if fp is not None:
    self.__super_init(fp, hdrs, url, code)

Which means the 'headers' slot in addinfourl is not initialized and
info() fails.  It is completely insane that urllib2 decides not to
initialize its own base class sometimes.

Change-Id: I32a0d738f71bdd7d38d86078b71d9001e26f1ec3
Signed-off-by: Shawn O. Pearce <>
diff --git a/ b/
index 43f4713..76d4d0d 100644
--- a/
+++ b/
@@ -1465,10 +1465,16 @@
         r = urllib2.urlopen(req)
       except urllib2.HTTPError, e:
+        def _content_type():
+          try:
+            return['content-type']
+          except:
+            return None
         if e.code == 404:
           keep = False
           return False
-        elif['content-type'] == 'text/plain':
+        elif _content_type() == 'text/plain':
             msg =
             if len(msg) > 0 and msg[-1] == '\n':