• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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    @property
77    def status(self):
78        return self.code
79
80    def getcode(self):
81        return self.code
82
83    def geturl(self):
84        return self.url
85