diff -r fb70ea8b7b2d Lib/test/test_urlparse.py --- a/Lib/test/test_urlparse.py Tue Apr 26 09:31:11 2016 +0300 +++ b/Lib/test/test_urlparse.py Tue Apr 26 16:22:05 2016 +0300 @@ -800,6 +800,113 @@ class UrlParseTestCase(unittest.TestCase with self.assertRaisesRegex(TypeError, "Cannot mix str"): urllib.parse.urljoin(b"http://python.org", "http://python.org") + def test_false_args(self): + from urllib.parse import (urlparse, urlsplit, urlunparse, urlunsplit, + urldefrag, parse_qsl) + + self.assertWarns(DeprecationWarning, urlparse, None) + self.assertWarns(DeprecationWarning, urlparse, ()) + self.assertEqual(urlparse(b'www.python.org', ''), urlparse(b'www.python.org')) + self.assertWarns(DeprecationWarning, urlparse, 'www.python.org', b'') + + self.assertWarns(DeprecationWarning, urlsplit, None) + self.assertWarns(DeprecationWarning, urlsplit, ()) + self.assertEqual(urlsplit(b'www.python.org', ''), urlsplit(b'www.python.org')) + self.assertWarns(DeprecationWarning, urlsplit, 'www.python.org', b'') + + with self.assertRaises(TypeError): + urlunparse((b"", "www.python.org", "", "", "", "")) + with self.assertWarns(DeprecationWarning), self.assertRaises(TypeError): + urlunparse((None, "www.python.org", "", "", "", "")) + with self.assertWarns(DeprecationWarning): + urlunparse(("http", b"", "", "", "", "")) + with self.assertWarns(DeprecationWarning): + urlunparse(("http", None, "", "", "", "")) + with self.assertWarns(DeprecationWarning), self.assertRaises(TypeError): + urlunparse(("http", "www.python.org", b"", "", "", "")) + with self.assertWarns(DeprecationWarning), self.assertRaises(TypeError): + urlunparse(("http", "www.python.org", None, "", "", "")) + with self.assertWarns(DeprecationWarning): + urlunparse(("http", "www.python.org", "", b"", "", "")) + with self.assertWarns(DeprecationWarning): + urlunparse(("http", "www.python.org", "", None, "", "")) + with self.assertWarns(DeprecationWarning): + urlunparse(("http", "www.python.org", "", "", b"", "")) + with self.assertWarns(DeprecationWarning): + urlunparse(("http", "www.python.org", "", "", None, "")) + with self.assertWarns(DeprecationWarning): + urlunparse(("http", "www.python.org", "", "", "", b"")) + with self.assertWarns(DeprecationWarning): + urlunparse(("http", "www.python.org", "", "", "", None)) + with self.assertRaises(TypeError): + urlunparse(("", b"www.python.org", b"", b"", b"", b"")) + with self.assertWarns(DeprecationWarning): + urlunparse((None, b"www.python.org", b"", b"", b"", b"")) + with self.assertWarns(DeprecationWarning): + urlunparse((b"http", "", b"", b"", b"", b"")) + with self.assertWarns(DeprecationWarning): + urlunparse((b"http", None, b"", b"", b"", b"")) + with self.assertWarns(DeprecationWarning): + urlunparse((b"http", b"www.python.org", "", b"", b"", b"")) + with self.assertWarns(DeprecationWarning): + urlunparse((b"http", b"www.python.org", None, b"", b"", b"")) + with self.assertWarns(DeprecationWarning): + urlunparse((b"http", b"www.python.org", b"", "", b"", b"")) + with self.assertWarns(DeprecationWarning): + urlunparse((b"http", b"www.python.org", b"", None, b"", b"")) + with self.assertWarns(DeprecationWarning): + urlunparse((b"http", b"www.python.org", b"", b"", "", b"")) + with self.assertWarns(DeprecationWarning): + urlunparse((b"http", b"www.python.org", b"", b"", None, b"")) + with self.assertWarns(DeprecationWarning): + urlunparse((b"http", b"www.python.org", b"", b"", b"", "")) + with self.assertWarns(DeprecationWarning): + urlunparse((b"http", b"www.python.org", b"", b"", b"", None)) + + with self.assertRaises(TypeError): + urlunsplit((b"", "www.python.org", "", "", "")) + with self.assertWarns(DeprecationWarning), self.assertRaises(TypeError): + urlunsplit((None, "www.python.org", "", "", "")) + with self.assertWarns(DeprecationWarning): + urlunsplit(("http", b"", "", "", "")) + with self.assertWarns(DeprecationWarning): + urlunsplit(("http", None, "", "", "")) + with self.assertWarns(DeprecationWarning), self.assertRaises(TypeError): + urlunsplit(("http", "www.python.org", b"", "", "")) + with self.assertWarns(DeprecationWarning), self.assertRaises(TypeError): + urlunsplit(("http", "www.python.org", None, "", "")) + with self.assertWarns(DeprecationWarning): + urlunsplit(("http", "www.python.org", "", b"", "")) + with self.assertWarns(DeprecationWarning): + urlunsplit(("http", "www.python.org", "", None, "")) + with self.assertWarns(DeprecationWarning): + urlunsplit(("http", "www.python.org", "", "", b"")) + with self.assertWarns(DeprecationWarning): + urlunsplit(("http", "www.python.org", "", "", None)) + with self.assertRaises(TypeError): + urlunsplit(("", b"www.python.org", b"", b"", b"")) + with self.assertWarns(DeprecationWarning): + urlunsplit((None, b"www.python.org", b"", b"", b"")) + with self.assertWarns(DeprecationWarning): + urlunsplit((b"http", "", b"", b"", b"")) + with self.assertWarns(DeprecationWarning): + urlunsplit((b"http", None, b"", b"", b"")) + with self.assertWarns(DeprecationWarning): + urlunsplit((b"http", b"www.python.org", "", b"", b"")) + with self.assertWarns(DeprecationWarning): + urlunsplit((b"http", b"www.python.org", None, b"", b"")) + with self.assertWarns(DeprecationWarning): + urlunsplit((b"http", b"www.python.org", b"", "", b"")) + with self.assertWarns(DeprecationWarning): + urlunsplit((b"http", b"www.python.org", b"", None, b"")) + with self.assertWarns(DeprecationWarning): + urlunsplit((b"http", b"www.python.org", b"", b"", "")) + with self.assertWarns(DeprecationWarning): + urlunsplit((b"http", b"www.python.org", b"", b"", None)) + + self.assertWarns(DeprecationWarning, urldefrag, None) + self.assertWarns(DeprecationWarning, parse_qsl, None) + def _check_result_type(self, str_type): num_args = len(str_type._fields) bytes_type = str_type._encoded_counterpart diff -r fb70ea8b7b2d Lib/urllib/parse.py --- a/Lib/urllib/parse.py Tue Apr 26 09:31:11 2016 +0300 +++ b/Lib/urllib/parse.py Tue Apr 26 16:22:05 2016 +0300 @@ -103,12 +103,26 @@ def _coerce_args(*args): # an appropriate result coercion function # - noop for str inputs # - encoding function otherwise - str_input = isinstance(args[0], str) + arg = args[0] + if isinstance(arg, str): + str_input = True + else: + str_input = False + if not (arg or hasattr(arg, 'decode')): + import warnings + warnings.warn('Use of %r is deprecated' % (arg,), + DeprecationWarning, 3) for arg in args[1:]: - # We special-case the empty string to support the - # "scheme=''" default argument to some functions - if arg and isinstance(arg, str) != str_input: + if isinstance(arg, str) == str_input and (str_input or arg or hasattr(arg, 'decode')): + continue + + if arg: raise TypeError("Cannot mix str and non-str arguments") + else: + import warnings + warnings.warn('Use of %r is deprecated' % (arg,), + DeprecationWarning, 3) + if str_input: return args + (_noop,) return _decode_args(args) + (_encode_result,) @@ -347,12 +361,19 @@ def _fix_result_transcoding(): _fix_result_transcoding() del _fix_result_transcoding -def urlparse(url, scheme='', allow_fragments=True): +_sentinel = object() + +def urlparse(url, scheme=_sentinel, allow_fragments=True): """Parse a URL into 6 components: :///;?# Return a 6-tuple: (scheme, netloc, path, params, query, fragment). Note that we don't break the components up in smaller bits (e.g. netloc is a single string) and we don't expand % escapes.""" + if scheme is _sentinel or isinstance(scheme, str) and scheme == '': + try: + scheme = url[:0] + except TypeError: + scheme = '' # causes DeprecationWarning later url, scheme, _coerce_result = _coerce_args(url, scheme) splitresult = urlsplit(url, scheme, allow_fragments) scheme, netloc, url, query, fragment = splitresult @@ -380,12 +401,17 @@ def _splitnetloc(url, start=0): delim = min(delim, wdelim) # use earliest delim position return url[start:delim], url[delim:] # return (domain, rest) -def urlsplit(url, scheme='', allow_fragments=True): +def urlsplit(url, scheme=_sentinel, allow_fragments=True): """Parse a URL into 5 components: :///?# Return a 5-tuple: (scheme, netloc, path, query, fragment). Note that we don't break the components up in smaller bits (e.g. netloc is a single string) and we don't expand % escapes.""" + if scheme is _sentinel or isinstance(scheme, str) and scheme == '': + try: + scheme = url[:0] + except TypeError: + scheme = '' # causes DeprecationWarning later url, scheme, _coerce_result = _coerce_args(url, scheme) allow_fragments = bool(allow_fragments) key = url, scheme, allow_fragments, type(url), type(scheme)