Skip to content

Commit 9b0d46d

Browse files
committed
#1178141: add addinfourl.code to get http status code from urllib.
1 parent dcd6b52 commit 9b0d46d

File tree

5 files changed

+36
-10
lines changed

5 files changed

+36
-10
lines changed

Doc/library/urllib.rst

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,17 @@ High-level interface
2727
a server somewhere on the network. If the connection cannot be made the
2828
:exc:`IOError` exception is raised. If all went well, a file-like object is
2929
returned. This supports the following methods: :meth:`read`, :meth:`readline`,
30-
:meth:`readlines`, :meth:`fileno`, :meth:`close`, :meth:`info` and
30+
:meth:`readlines`, :meth:`fileno`, :meth:`close`, :meth:`info`, :meth:`getcode` and
3131
:meth:`geturl`. It also has proper support for the :term:`iterator` protocol. One
3232
caveat: the :meth:`read` method, if the size argument is omitted or negative,
3333
may not read until the end of the data stream; there is no good way to determine
3434
that the entire stream from a socket has been read in the general case.
3535

36-
Except for the :meth:`info` and :meth:`geturl` methods, these methods have the
37-
same interface as for file objects --- see section :ref:`bltin-file-objects` in
38-
this manual. (It is not a built-in file object, however, so it can't be used at
39-
those few places where a true built-in file object is required.)
36+
Except for the :meth:`info`, :meth:`getcode` and :meth:`geturl` methods,
37+
these methods have the same interface as for file objects --- see section
38+
:ref:`bltin-file-objects` in this manual. (It is not a built-in file object,
39+
however, so it can't be used at those few places where a true built-in file
40+
object is required.)
4041

4142
.. index:: module: mimetools
4243

@@ -58,6 +59,9 @@ High-level interface
5859
the client was redirected to. The :meth:`geturl` method can be used to get at
5960
this redirected URL.
6061

62+
The :meth:`getcode` method returns the HTTP status code that was sent with the
63+
response, or ``None`` if the URL is no HTTP URL.
64+
6165
If the *url* uses the :file:`http:` scheme identifier, the optional *data*
6266
argument may be given to specify a ``POST`` request (normally the request type
6367
is ``GET``). The *data* argument must be in standard

Lib/test/test_urllib.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ def tearDown(self):
4747
def test_interface(self):
4848
# Make sure object returned by urlopen() has the specified methods
4949
for attr in ("read", "readline", "readlines", "fileno",
50-
"close", "info", "geturl", "__iter__"):
50+
"close", "info", "geturl", "getcode", "__iter__"):
5151
self.assert_(hasattr(self.returned_obj, attr),
5252
"object returned by urlopen() lacks %s attribute" %
5353
attr)
@@ -87,6 +87,9 @@ def test_info(self):
8787
def test_geturl(self):
8888
self.assertEqual(self.returned_obj.geturl(), self.pathname)
8989

90+
def test_getcode(self):
91+
self.assertEqual(self.returned_obj.getcode(), None)
92+
9093
def test_iter(self):
9194
# Test iterator
9295
# Don't need to count number of iterations since test would fail the
@@ -123,6 +126,8 @@ def test_read(self):
123126
fp = urllib.urlopen("http://python.org/")
124127
self.assertEqual(fp.readline(), 'Hello!')
125128
self.assertEqual(fp.readline(), '')
129+
self.assertEqual(fp.geturl(), 'http://python.org/')
130+
self.assertEqual(fp.getcode(), 200)
126131
finally:
127132
self.unfakehttp()
128133

Lib/test/test_urllibnet.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,16 @@ def test_geturl(self):
8383
open_url.close()
8484
self.assertEqual(gotten_url, URL)
8585

86+
def test_getcode(self):
87+
# test getcode() with the fancy opener to get 404 error codes
88+
URL = "http://www.python.org/XXXinvalidXXX"
89+
open_url = urllib.FancyURLopener().open(URL)
90+
try:
91+
code = open_url.getcode()
92+
finally:
93+
open_url.close()
94+
self.assertEqual(code, 404)
95+
8696
def test_fileno(self):
8797
if (sys.platform in ('win32',) or
8898
not hasattr(os, 'fdopen')):

Lib/urllib.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ def open_http(self, url, data=None):
343343
# According to RFC 2616, "2xx" code indicates that the client's
344344
# request was successfully received, understood, and accepted.
345345
if (200 <= errcode < 300):
346-
return addinfourl(fp, headers, "http:" + url)
346+
return addinfourl(fp, headers, "http:" + url, errcode)
347347
else:
348348
if data is None:
349349
return self.http_error(url, fp, errcode, errmsg, headers)
@@ -438,7 +438,7 @@ def open_https(self, url, data=None):
438438
# According to RFC 2616, "2xx" code indicates that the client's
439439
# request was successfully received, understood, and accepted.
440440
if (200 <= errcode < 300):
441-
return addinfourl(fp, headers, "https:" + url)
441+
return addinfourl(fp, headers, "https:" + url, errcode)
442442
else:
443443
if data is None:
444444
return self.http_error(url, fp, errcode, errmsg, headers)
@@ -610,7 +610,7 @@ def __init__(self, *args, **kwargs):
610610

611611
def http_error_default(self, url, fp, errcode, errmsg, headers):
612612
"""Default error handling -- don't raise an exception."""
613-
return addinfourl(fp, headers, "http:" + url)
613+
return addinfourl(fp, headers, "http:" + url, errcode)
614614

615615
def http_error_302(self, url, fp, errcode, errmsg, headers, data=None):
616616
"""Error 302 -- relocated (temporarily)."""
@@ -953,14 +953,18 @@ def info(self):
953953
class addinfourl(addbase):
954954
"""class to add info() and geturl() methods to an open file."""
955955

956-
def __init__(self, fp, headers, url):
956+
def __init__(self, fp, headers, url, code=None):
957957
addbase.__init__(self, fp)
958958
self.headers = headers
959959
self.url = url
960+
self.code = code
960961

961962
def info(self):
962963
return self.headers
963964

965+
def getcode(self):
966+
return self.code
967+
964968
def geturl(self):
965969
return self.url
966970

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,9 @@ Core and builtins
369369
Library
370370
-------
371371

372+
- #1178141: add a getcode() method to the addinfourls that urllib.open()
373+
returns so that you can retrieve the HTTP status code.
374+
372375
- Issue #1003: Fix zipfile decryption check, it would fail zip files
373376
with extended local headers.
374377

0 commit comments

Comments
 (0)