Skip to content

Commit

Permalink
Undo pathlib changes
Browse files Browse the repository at this point in the history
  • Loading branch information
barneygale committed Feb 22, 2023
1 parent 64fc342 commit 86c0408
Showing 1 changed file with 28 additions and 52 deletions.
80 changes: 28 additions & 52 deletions Lib/pathlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,49 +60,38 @@ class _Flavour(object):
def __init__(self):
self.join = self.sep.join

def _split_part(self, part):
"""
Return the drive, root and path parts from a given part.
If the part is a tuple, it already contains these values and therefore is returned.
Otherwise, splitroot is used to parse the part.
"""
if isinstance(part, tuple):
return part
elif isinstance(part, str):
if self.altsep:
part = part.replace(self.altsep, self.sep)
drv, root, rel = self.splitroot(part)
return drv, root, rel.split(self.sep)
else:
raise TypeError(f'argument should be a tuple or an str object, not {type(part)}')

def parse_parts(self, parts):
"""
Parse and join multiple path strings, and
return a tuple of the final drive, root and path parts.
The given parts can be either strings of paths,
or tuples that represent paths, containing the drive, root and list of path parts.
The option for passing a tuple is needed, as the part 'a:b' could be interpreted
either as the relative path 'b' with the drive 'a:',
or as a file 'a' with the NTFS data-stream 'b'.
For example, passing either ('a:', '', ['b']) or ('', '', ['a:b']) instead of 'a:b'
will allow parse_parts to behave properly in these cases.
"""
parsed = []
sep = self.sep
altsep = self.altsep
drv = root = ''
it = reversed(parts)
for part in it:
if not part:
continue
current_drv, current_root, rel_parts = self._split_part(part)
if not drv:
drv = current_drv
if not root:
root = current_root
for x in reversed(rel_parts):
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))
if root and drv:
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)
Expand All @@ -126,9 +115,6 @@ def join_parsed_parts(self, drv, root, parts, drv2, root2, parts2):
return drv, root, parts + parts2
return drv2, root2, parts2

def has_drive(self, part):
return self.splitroot(part)[0] != ''


class _WindowsFlavour(_Flavour):
# Reference for Windows paths can be found at
Expand Down Expand Up @@ -208,21 +194,18 @@ def resolve(self, path, strict=False):
s = str(path)
if not s:
return os.getcwd()
previous_s = None
if _getfinalpathname is not None:
if strict:
return self._ext_to_normal(_getfinalpathname(s))
else:
previous_s = None
tail_parts = [] # End of the path after the first one not found
while True:
try:
s = self._ext_to_normal(_getfinalpathname(s))
except FileNotFoundError:
previous_s = s
s, tail = os.path.split(s)
if self.has_drive(tail):
# To avoid confusing between a filename with a data-stream and a drive letter
tail = f'.{self.sep}{tail}'
tail_parts.append(tail)
if previous_s == s:
return path
Expand Down Expand Up @@ -670,10 +653,7 @@ def _parse_args(cls, args):
parts = []
for a in args:
if isinstance(a, PurePath):
path_parts = a._parts
if a._drv or a._root:
path_parts = path_parts[1:]
parts.append((a._drv, a._root, path_parts))
parts += a._parts
else:
a = os.fspath(a)
if isinstance(a, str):
Expand Down Expand Up @@ -711,10 +691,6 @@ def _from_parsed_parts(cls, drv, root, parts, init=True):

@classmethod
def _format_parsed_parts(cls, drv, root, parts):
if parts and not drv and cls._flavour.has_drive(parts[0]):
# In case there is no drive, and the first part might be interpreted as a drive,
# we add a dot to clarify the first part is not a drive.
parts = ['.'] + parts
if drv or root:
return drv + root + cls._flavour.join(parts[1:])
else:
Expand Down Expand Up @@ -965,7 +941,7 @@ def __truediv__(self, key):

def __rtruediv__(self, key):
try:
return self._from_parts([key, self])
return self._from_parts([key] + self._parts)
except TypeError:
return NotImplemented

Expand Down Expand Up @@ -1195,7 +1171,7 @@ def absolute(self):
return self
# FIXME this must defer to the specific flavour (and, under Windows,
# use nt._getfullpathname())
obj = self._from_parts([os.getcwd(), self], init=False)
obj = self._from_parts([os.getcwd()] + self._parts, init=False)
obj._init(template=self)
return obj

Expand Down Expand Up @@ -1577,7 +1553,7 @@ def expanduser(self):
if (not (self._drv or self._root) and
self._parts and self._parts[0][:1] == '~'):
homedir = self._flavour.gethomedir(self._parts[0][1:])
return self._from_parts([homedir, self.relative_to(self._parts[0])])
return self._from_parts([homedir] + self._parts[1:])

return self

Expand Down

0 comments on commit 86c0408

Please sign in to comment.