diff --git a/Lib/test/test_urlparse.py b/Lib/test/test_urlparse.py index 80fb9e5cd2a445..661bc4642f41a1 100644 --- a/Lib/test/test_urlparse.py +++ b/Lib/test/test_urlparse.py @@ -437,6 +437,12 @@ def test_urljoins(self): # issue 23703: don't duplicate filename self.checkJoin('a', 'b', 'b') + # issue 32779: clear the query string when joining with '?' + self.checkJoin('http://a/b/c?d=e', '?', 'http://a/b/c') + self.checkJoin('http://a/b/c?d=e', 'http:?', 'http://a/b/c') + self.checkJoin('http://a/b/c#d?e=f', '?#g', 'http://a/b/c#g') + self.checkJoin('http://a/b/c?d=e#f', '#?', 'http://a/b/c?d=e#?') + def test_RFC2732(self): str_cases = [ ('http://Test.python.org:5432/foo/', 'test.python.org', 5432), diff --git a/Lib/urllib/parse.py b/Lib/urllib/parse.py index 5f95c5ff7f9c1c..1908642e8b1e16 100644 --- a/Lib/urllib/parse.py +++ b/Lib/urllib/parse.py @@ -535,7 +535,10 @@ def urljoin(base, url, allow_fragments=True): if not path and not params: path = bpath params = bparams - if not query: + # since urlparse doesn't leave any evidence of whether there was a bare + # '?' with an empty query string, we need to check whether it was there. + has_empty_query = url[0] == '?' or url.startswith(scheme + ':?') + if not has_empty_query: query = bquery return _coerce_result(urlunparse((scheme, netloc, path, params, query, fragment))) diff --git a/Misc/NEWS.d/next/Library/2018-02-12-17-12-45.bpo-32779.FYzcZd.rst b/Misc/NEWS.d/next/Library/2018-02-12-17-12-45.bpo-32779.FYzcZd.rst new file mode 100644 index 00000000000000..6729499008d9f0 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-02-12-17-12-45.bpo-32779.FYzcZd.rst @@ -0,0 +1 @@ +Fix urljoining with '?', a URL containing only a bare query string.