diff -r 436b606ecfe8 Lib/test/test_urlparse.py --- a/Lib/test/test_urlparse.py Wed Sep 25 07:14:41 2013 -0700 +++ b/Lib/test/test_urlparse.py Thu Sep 26 18:09:57 2013 +0800 @@ -679,6 +679,17 @@ urllib.parse.urljoin("http://python.org", b"http://python.org") with self.assertRaisesRegex(TypeError, "Cannot mix str"): urllib.parse.urljoin(b"http://python.org", "http://python.org") + # issue 19094 + with self.assertRaisesRegex(TypeError, "Cannot mix str"): + urllib.parse.urljoin("http://python.org", b"") + with self.assertRaisesRegex(TypeError, "Cannot mix str"): + urllib.parse.urljoin(b"http://python.org", "") + with self.assertRaisesRegex(TypeError, "Cannot mix str"): + urllib.parse.urljoin("http://python.org", []) + with self.assertRaisesRegex(TypeError, "Cannot mix bytes"): + urllib.parse.urljoin(b"http://python.org", []) + with self.assertRaisesRegex(TypeError, "Cannot mix bytes"): + urllib.parse.urljoin(bytearray(b"http://python.org"), []) def _check_result_type(self, str_type): num_args = len(str_type._fields) diff -r 436b606ecfe8 Lib/urllib/parse.py --- a/Lib/urllib/parse.py Wed Sep 25 07:14:41 2013 -0700 +++ b/Lib/urllib/parse.py Thu Sep 26 18:09:57 2013 +0800 @@ -405,6 +405,14 @@ def urljoin(base, url, allow_fragments=True): """Join a base URL and a possibly relative URL to form an absolute interpretation of the latter.""" + base_str = isinstance(base, str) + url_str = isinstance(url, str) + if base_str != url_str: + raise TypeError("Cannot mix str and non-str arguments") + base_bytes = any((isinstance(base, bytes), isinstance(base, bytearray))) + url_bytes = any((isinstance(url, bytes), isinstance(url, bytearray))) + if base_bytes != url_bytes: + raise TypeError("Cannot mix bytes and non-bytes arguments") if not base: return url if not url: