]> granicus.if.org Git - python/commitdiff
#1178141: add addinfourl.code to get http status code from urllib.
authorGeorg Brandl <georg@python.org>
Sun, 20 Jan 2008 11:43:03 +0000 (11:43 +0000)
committerGeorg Brandl <georg@python.org>
Sun, 20 Jan 2008 11:43:03 +0000 (11:43 +0000)
Doc/library/urllib.rst
Lib/test/test_urllib.py
Lib/test/test_urllibnet.py
Lib/urllib.py
Misc/NEWS

index 1856ccac468470d86c117d114275b54e5007c816..3ec6e881df8e01f4bdb9983fd6b7a73a6dd52850 100644 (file)
@@ -27,16 +27,17 @@ High-level interface
    a server somewhere on the network.  If the connection cannot be made the
    :exc:`IOError` exception is raised.  If all went well, a file-like object is
    returned.  This supports the following methods: :meth:`read`, :meth:`readline`,
-   :meth:`readlines`, :meth:`fileno`, :meth:`close`, :meth:`info` and
+   :meth:`readlines`, :meth:`fileno`, :meth:`close`, :meth:`info`, :meth:`getcode` and
    :meth:`geturl`.  It also has proper support for the :term:`iterator` protocol. One
    caveat: the :meth:`read` method, if the size argument is omitted or negative,
    may not read until the end of the data stream; there is no good way to determine
    that the entire stream from a socket has been read in the general case.
 
-   Except for the :meth:`info` and :meth:`geturl` methods, these methods have the
-   same interface as for file objects --- see section :ref:`bltin-file-objects` in
-   this manual.  (It is not a built-in file object, however, so it can't be used at
-   those few places where a true built-in file object is required.)
+   Except for the :meth:`info`, :meth:`getcode` and :meth:`geturl` methods,
+   these methods have the same interface as for file objects --- see section
+   :ref:`bltin-file-objects` in this manual.  (It is not a built-in file object,
+   however, so it can't be used at those few places where a true built-in file
+   object is required.)
 
    .. index:: module: mimetools
 
@@ -58,6 +59,9 @@ High-level interface
    the client was redirected to.  The :meth:`geturl` method can be used to get at
    this redirected URL.
 
+   The :meth:`getcode` method returns the HTTP status code that was sent with the
+   response, or ``None`` if the URL is no HTTP URL.
+
    If the *url* uses the :file:`http:` scheme identifier, the optional *data*
    argument may be given to specify a ``POST`` request (normally the request type
    is ``GET``).  The *data* argument must be in standard
index ed7f6ceb4de885ac9d3b01f1610433b7785b76c6..455e7fc7fe539faf64bd67fe2304802f24715715 100644 (file)
@@ -47,7 +47,7 @@ class urlopen_FileTests(unittest.TestCase):
     def test_interface(self):
         # Make sure object returned by urlopen() has the specified methods
         for attr in ("read", "readline", "readlines", "fileno",
-                     "close", "info", "geturl", "__iter__"):
+                     "close", "info", "geturl", "getcode", "__iter__"):
             self.assert_(hasattr(self.returned_obj, attr),
                          "object returned by urlopen() lacks %s attribute" %
                          attr)
@@ -87,6 +87,9 @@ class urlopen_FileTests(unittest.TestCase):
     def test_geturl(self):
         self.assertEqual(self.returned_obj.geturl(), self.pathname)
 
+    def test_getcode(self):
+        self.assertEqual(self.returned_obj.getcode(), None)
+
     def test_iter(self):
         # Test iterator
         # Don't need to count number of iterations since test would fail the
@@ -123,6 +126,8 @@ class urlopen_HttpTests(unittest.TestCase):
             fp = urllib.urlopen("http://python.org/")
             self.assertEqual(fp.readline(), 'Hello!')
             self.assertEqual(fp.readline(), '')
+            self.assertEqual(fp.geturl(), 'http://python.org/')
+            self.assertEqual(fp.getcode(), 200)
         finally:
             self.unfakehttp()
 
index 9105afe42af96f4b57581742c91994220dce44a7..a28c081569a6b4344ce2cd71673c3a1ba741832e 100644 (file)
@@ -83,6 +83,16 @@ class urlopenNetworkTests(unittest.TestCase):
             open_url.close()
         self.assertEqual(gotten_url, URL)
 
+    def test_getcode(self):
+        # test getcode() with the fancy opener to get 404 error codes
+        URL = "http://www.python.org/XXXinvalidXXX"
+        open_url = urllib.FancyURLopener().open(URL)
+        try:
+            code = open_url.getcode()
+        finally:
+            open_url.close()
+        self.assertEqual(code, 404)
+
     def test_fileno(self):
         if (sys.platform in ('win32',) or
                 not hasattr(os, 'fdopen')):
index c6751b8f23d982ff85e29d477e6a75b0d4708c62..4a49fc026e5f3f56ee7fb3b08c2e48c41107c7a0 100644 (file)
@@ -343,7 +343,7 @@ class URLopener:
         # According to RFC 2616, "2xx" code indicates that the client's
         # request was successfully received, understood, and accepted.
         if (200 <= errcode < 300):
-            return addinfourl(fp, headers, "http:" + url)
+            return addinfourl(fp, headers, "http:" + url, errcode)
         else:
             if data is None:
                 return self.http_error(url, fp, errcode, errmsg, headers)
@@ -438,7 +438,7 @@ class URLopener:
             # According to RFC 2616, "2xx" code indicates that the client's
             # request was successfully received, understood, and accepted.
             if (200 <= errcode < 300):
-                return addinfourl(fp, headers, "https:" + url)
+                return addinfourl(fp, headers, "https:" + url, errcode)
             else:
                 if data is None:
                     return self.http_error(url, fp, errcode, errmsg, headers)
@@ -610,7 +610,7 @@ class FancyURLopener(URLopener):
 
     def http_error_default(self, url, fp, errcode, errmsg, headers):
         """Default error handling -- don't raise an exception."""
-        return addinfourl(fp, headers, "http:" + url)
+        return addinfourl(fp, headers, "http:" + url, errcode)
 
     def http_error_302(self, url, fp, errcode, errmsg, headers, data=None):
         """Error 302 -- relocated (temporarily)."""
@@ -953,14 +953,18 @@ class addinfo(addbase):
 class addinfourl(addbase):
     """class to add info() and geturl() methods to an open file."""
 
-    def __init__(self, fp, headers, url):
+    def __init__(self, fp, headers, url, code=None):
         addbase.__init__(self, fp)
         self.headers = headers
         self.url = url
+        self.code = code
 
     def info(self):
         return self.headers
 
+    def getcode(self):
+        return self.code
+
     def geturl(self):
         return self.url
 
index 3d70408f0837c61fc2d00c036df2cc27d3c7aeb7..3ff4f3ece6c6951f0c40e17c45dfec037fd1200e 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -369,6 +369,9 @@ Core and builtins
 Library
 -------
 
+- #1178141: add a getcode() method to the addinfourls that urllib.open()
+  returns so that you can retrieve the HTTP status code.
+
 - Issue #1003: Fix zipfile decryption check, it would fail zip files
   with extended local headers.