mirror of https://github.com/python/cpython
gh-94909: fix joining of absolute and relative Windows paths in pathlib (GH-95450)
Have pathlib use `os.path.join()` to join arguments to the `PurePath` initialiser, which fixes a minor bug when handling relative paths with drives. Previously: ```python >>> from pathlib import PureWindowsPath >>> a = 'C:/a/b' >>> b = 'C:x/y' >>> PureWindowsPath(a, b) PureWindowsPath('C:x/y') ``` Now: ```python >>> PureWindowsPath(a, b) PureWindowsPath('C:/a/b/x/y') ```
This commit is contained in:
parent
a965db37f2
commit
187949ebf2
|
@ -61,41 +61,16 @@ class _Flavour(object):
|
|||
self.join = self.sep.join
|
||||
|
||||
def parse_parts(self, parts):
|
||||
parsed = []
|
||||
if not parts:
|
||||
return '', '', []
|
||||
sep = self.sep
|
||||
altsep = self.altsep
|
||||
drv = root = ''
|
||||
it = reversed(parts)
|
||||
for part in it:
|
||||
if not part:
|
||||
continue
|
||||
if altsep:
|
||||
part = part.replace(altsep, sep)
|
||||
drv, root, rel = self.splitroot(part)
|
||||
if sep in rel:
|
||||
for x in reversed(rel.split(sep)):
|
||||
if x and x != '.':
|
||||
parsed.append(sys.intern(x))
|
||||
else:
|
||||
if rel and rel != '.':
|
||||
parsed.append(sys.intern(rel))
|
||||
if drv or root:
|
||||
if not drv:
|
||||
# If no drive is present, try to find one in the previous
|
||||
# parts. This makes the result of parsing e.g.
|
||||
# ("C:", "/", "a") reasonably intuitive.
|
||||
for part in it:
|
||||
if not part:
|
||||
continue
|
||||
if altsep:
|
||||
part = part.replace(altsep, sep)
|
||||
drv = self.splitroot(part)[0]
|
||||
if drv:
|
||||
break
|
||||
break
|
||||
if drv or root:
|
||||
parsed.append(drv + root)
|
||||
parsed.reverse()
|
||||
path = self.pathmod.join(*parts)
|
||||
if altsep:
|
||||
path = path.replace(altsep, sep)
|
||||
drv, root, rel = self.splitroot(path)
|
||||
unfiltered_parsed = [drv + root] + rel.split(sep)
|
||||
parsed = [sys.intern(x) for x in unfiltered_parsed if x and x != '.']
|
||||
return drv, root, parsed
|
||||
|
||||
def join_parsed_parts(self, drv, root, parts, drv2, root2, parts2):
|
||||
|
|
|
@ -136,6 +136,10 @@ class NTFlavourTest(_BaseFlavourTest, unittest.TestCase):
|
|||
check(['a', '/b', 'c'], ('', '\\', ['\\', 'b', 'c']))
|
||||
check(['Z:/a', '/b', 'c'], ('Z:', '\\', ['Z:\\', 'b', 'c']))
|
||||
check(['//?/Z:/a', '/b', 'c'], ('\\\\?\\Z:', '\\', ['\\\\?\\Z:\\', 'b', 'c']))
|
||||
# Joining with the same drive => the first path is appended to if
|
||||
# the second path is relative.
|
||||
check(['c:/a/b', 'c:x/y'], ('c:', '\\', ['c:\\', 'a', 'b', 'x', 'y']))
|
||||
check(['c:/a/b', 'c:/x/y'], ('c:', '\\', ['c:\\', 'x', 'y']))
|
||||
|
||||
def test_splitroot(self):
|
||||
f = self.flavour.splitroot
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
Fix incorrect joining of relative Windows paths with drives in
|
||||
:class:`pathlib.PurePath` initializer.
|
Loading…
Reference in New Issue