diff -r b6fce698e467 Lib/pathlib.py --- a/Lib/pathlib.py Wed Dec 04 20:46:20 2013 +0100 +++ b/Lib/pathlib.py Fri Dec 06 15:32:21 2013 +0200 @@ -89,12 +89,16 @@ (drive, root, parts) tuples. Return a new (drive, root, parts) tuple. """ if root2: - parts = parts2 - root = root2 + if not drv2 and drv: + return drv, root2, [drv + root2] + parts2[1:] + elif drv2: + if drv2 == drv: + # Same drive => second path is relative to the first + return drv, root, parts + parts2[1:] else: - parts = parts + parts2 - # XXX raise error if drv and drv2 are different? - return drv2 or drv, root, parts + # Second path is non-anchored (common case) + return drv, root, parts + parts2 + return drv2, root2, parts2 class _WindowsFlavour(_Flavour): diff -r b6fce698e467 Lib/test/test_pathlib.py --- a/Lib/test/test_pathlib.py Wed Dec 04 20:46:20 2013 +0100 +++ b/Lib/test/test_pathlib.py Fri Dec 06 15:32:21 2013 +0200 @@ -975,6 +975,48 @@ self.assertTrue(P('//a/b/c').is_absolute()) self.assertTrue(P('//a/b/c/d').is_absolute()) + def test_join(self): + P = self.cls + p = P('C:/a/b') + pp = p.joinpath('x/y') + self.assertEqual(pp, P('C:/a/b/x/y')) + pp = p.joinpath('/x/y') + self.assertEqual(pp, P('C:/x/y')) + # Joining with a different drive => the first path is ignored, even + # if the second path is relative. + pp = p.joinpath('D:x/y') + self.assertEqual(pp, P('D:x/y')) + pp = p.joinpath('D:/x/y') + self.assertEqual(pp, P('D:/x/y')) + pp = p.joinpath('//host/share/x/y') + self.assertEqual(pp, P('//host/share/x/y')) + # Joining with the same drive => the first path is appended to if + # the second path is relative. + pp = p.joinpath('C:x/y') + self.assertEqual(pp, P('C:/a/b/x/y')) + pp = p.joinpath('C:/x/y') + self.assertEqual(pp, P('C:/x/y')) + + def test_div(self): + # Basically the same as joinpath() + P = self.cls + p = P('C:/a/b') + self.assertEqual(p / 'x/y', P('C:/a/b/x/y')) + self.assertEqual(p / 'x' / 'y', P('C:/a/b/x/y')) + self.assertEqual(p / '/x/y', P('C:/x/y')) + self.assertEqual(p / '/x' / 'y', P('C:/x/y')) + # Joining with a different drive => the first path is ignored, even + # if the second path is relative. + self.assertEqual(p / 'D:x/y', P('D:x/y')) + self.assertEqual(p / 'D:' / 'x/y', P('D:x/y')) + self.assertEqual(p / 'D:/x/y', P('D:/x/y')) + self.assertEqual(p / 'D:' / '/x/y', P('D:/x/y')) + self.assertEqual(p / '//host/share/x/y', P('//host/share/x/y')) + # Joining with the same drive => the first path is appended to if + # the second path is relative. + self.assertEqual(p / 'C:x/y', P('C:/a/b/x/y')) + self.assertEqual(p / 'C:/x/y', P('C:/x/y')) + def test_is_reserved(self): P = self.cls self.assertIs(False, P('').is_reserved())