diff -r 0780e969e30b Lib/test/test_urllib.py --- a/Lib/test/test_urllib.py Mon Mar 28 10:35:38 2011 -0700 +++ b/Lib/test/test_urllib.py Tue Mar 29 12:22:35 2011 -0700 @@ -170,6 +170,16 @@ finally: self.unfakehttp() + def test_url_fragment(self): + # Issue #11703: geturl() omits fragments in the original URL. + url = 'http://docs.python.org/library/urllib.html#OK' + self.fakehttp(b'Hello!') + try: + fp = urllib.request.urlopen(url) + self.assertEqual(fp.geturl(), url) + finally: + self.unfakehttp() + def test_read_bogus(self): # urlopen() should raise IOError for many error codes. self.fakehttp(b'''HTTP/1.1 401 Authentication Required diff -r 0780e969e30b Lib/test/test_urllib2.py --- a/Lib/test/test_urllib2.py Mon Mar 28 10:35:38 2011 -0700 +++ b/Lib/test/test_urllib2.py Tue Mar 29 12:22:35 2011 -0700 @@ -1315,12 +1315,16 @@ req = Request("") self.assertEqual("www.python.org", req.get_host()) - def test_urlwith_fragment(self): + def test_url_fragment(self): req = Request("http://www.python.org/?qs=query#fragment=true") self.assertEqual("/?qs=query", req.get_selector()) req = Request("http://www.python.org/#fun=true") self.assertEqual("/", req.get_selector()) + # Issue 11703: geturl() omits fragment in the original URL. + url = 'http://docs.python.org/library/urllib2.html#OK' + req = Request(url) + self.assertEqual(req.get_full_url(), url) def test_main(verbose=None): from test import test_urllib2 diff -r 0780e969e30b Lib/urllib/request.py --- a/Lib/urllib/request.py Mon Mar 28 10:35:38 2011 -0700 +++ b/Lib/urllib/request.py Tue Mar 29 12:22:35 2011 -0700 @@ -163,7 +163,7 @@ origin_req_host=None, unverifiable=False): # unwrap('') --> 'type://host/path' self.full_url = unwrap(url) - self.full_url, fragment = splittag(self.full_url) + self.full_url, self.fragment = splittag(self.full_url) self.data = data self.headers = {} self._tunnel_host = None @@ -202,7 +202,10 @@ return self.data def get_full_url(self): - return self.full_url + if self.fragment: + return '%s#%s' % (self.full_url, self.fragment) + else: + return self.full_url def get_type(self): return self.type @@ -1095,7 +1098,7 @@ except socket.error as err: raise URLError(err) - r.url = req.full_url + r.url = req.get_full_url() # This line replaces the .msg attribute of the HTTPResponse # with .headers, because urllib clients expect the response to # have the reason in .msg. It would be good to mark this