diff --git a/Lib/posixpath.py b/Lib/posixpath.py --- a/Lib/posixpath.py +++ b/Lib/posixpath.py @@ -74,13 +74,21 @@ will be discarded.""" sep = _get_sep(a) path = a - for b in p: - if b.startswith(sep): - path = b - elif not path or path.endswith(sep): - path += b + try: + for b in p: + if b.startswith(sep): + path = b + elif not path or path.endswith(sep): + path += b + else: + path += sep + b + except TypeError: + strs = [isinstance(s, str) for s in (a, ) + p] + if any(strs) and not all(strs): + raise TypeError('You can\'t mix strings and bytes in path ' + 'components.') from None else: - path += sep + b + raise return path diff --git a/Lib/test/test_posixpath.py b/Lib/test/test_posixpath.py --- a/Lib/test/test_posixpath.py +++ b/Lib/test/test_posixpath.py @@ -58,6 +58,18 @@ self.assertRaises(TypeError, posixpath.join, b"bytes", "str") self.assertRaises(TypeError, posixpath.join, "str", b"bytes") + try: + posixpath.join(b'bytes', 'str') + except TypeError as e: + self.assertIn('You can\'t mix strings and bytes', e.args[0]) + try: + posixpath.join('str', b'bytes') + except TypeError as e: + self.assertIn('You can\'t mix strings and bytes', e.args[0]) + try: + posixpath.join('str', bytearray(b'bytes')) + except TypeError as e: + self.assertIn('You can\'t mix strings and bytes', e.args[0]) def test_split(self): self.assertEqual(posixpath.split("/foo/bar"), ("/foo", "bar"))