1"""Response classes used by urllib. 2 3The base class, addbase, defines a minimal file-like interface, 4including read() and readline(). The typical response object is an 5addinfourl instance, which defines an info() method that returns 6headers and a geturl() method that returns the url. 7""" 8 9import tempfile 10 11__all__ = ['addbase', 'addclosehook', 'addinfo', 'addinfourl'] 12 13 14class addbase(tempfile._TemporaryFileWrapper): 15 """Base class for addinfo and addclosehook. Is a good idea for garbage collection.""" 16 17 # XXX Add a method to expose the timeout on the underlying socket? 18 19 def __init__(self, fp): 20 super(addbase, self).__init__(fp, '<urllib response>', delete=False) 21 # Keep reference around as this was part of the original API. 22 self.fp = fp 23 24 def __repr__(self): 25 return '<%s at %r whose fp = %r>' % (self.__class__.__name__, 26 id(self), self.file) 27 28 def __enter__(self): 29 if self.fp.closed: 30 raise ValueError("I/O operation on closed file") 31 return self 32 33 def __exit__(self, type, value, traceback): 34 self.close() 35 36 37class addclosehook(addbase): 38 """Class to add a close hook to an open file.""" 39 40 def __init__(self, fp, closehook, *hookargs): 41 super(addclosehook, self).__init__(fp) 42 self.closehook = closehook 43 self.hookargs = hookargs 44 45 def close(self): 46 try: 47 closehook = self.closehook 48 hookargs = self.hookargs 49 if closehook: 50 self.closehook = None 51 self.hookargs = None 52 closehook(*hookargs) 53 finally: 54 super(addclosehook, self).close() 55 56 57class addinfo(addbase): 58 """class to add an info() method to an open file.""" 59 60 def __init__(self, fp, headers): 61 super(addinfo, self).__init__(fp) 62 self.headers = headers 63 64 def info(self): 65 return self.headers 66 67 68class addinfourl(addinfo): 69 """class to add info() and geturl() methods to an open file.""" 70 71 def __init__(self, fp, headers, url, code=None): 72 super(addinfourl, self).__init__(fp, headers) 73 self.url = url 74 self.code = code 75 76 def getcode(self): 77 return self.code 78 79 def geturl(self): 80 return self.url 81