summaryrefslogtreecommitdiffstats
path: root/Lib/pathlib
diff options
context:
space:
mode:
authorBarney Gale <barney.gale@gmail.com>2024-11-09 18:47:49 (GMT)
committerGitHub <noreply@github.com>2024-11-09 18:47:49 (GMT)
commit266328552e922fd9030cd699e10a25f03a67c8ba (patch)
tree5a210ddb5613acd82d11e112959972ed4d4a7a84 /Lib/pathlib
parent0f47a3199c51ba7c49e72b4c645dbf599aa17be4 (diff)
downloadcpython-266328552e922fd9030cd699e10a25f03a67c8ba.zip
cpython-266328552e922fd9030cd699e10a25f03a67c8ba.tar.gz
cpython-266328552e922fd9030cd699e10a25f03a67c8ba.tar.bz2
pathlib ABCs: tighten up `resolve()` and `absolute()` (#126611)
In `PathBase.resolve()`, raise `UnsupportedOperation` if a non-POSIX path parser is used (our implementation uses `posixpath._realpath()`, which produces incorrect results for non-POSIX path flavours.) Also tweak code to call `self.absolute()` upfront rather than supplying an emulated `getcwd()` function. Adjust `PathBase.absolute()` to work somewhat like `resolve()`. If a POSIX path parser is used, we treat the root directory as the current directory. This is the simplest useful behaviour for concrete path types without a current directory cursor.
Diffstat (limited to 'Lib/pathlib')
-rw-r--r--Lib/pathlib/_abc.py23
1 files changed, 14 insertions, 9 deletions
diff --git a/Lib/pathlib/_abc.py b/Lib/pathlib/_abc.py
index e9e46e5..2c243d4 100644
--- a/Lib/pathlib/_abc.py
+++ b/Lib/pathlib/_abc.py
@@ -735,7 +735,13 @@ class PathBase(PurePathBase):
Use resolve() to resolve symlinks and remove '..' segments.
"""
- raise UnsupportedOperation(self._unsupported_msg('absolute()'))
+ if self.is_absolute():
+ return self
+ elif self.parser is not posixpath:
+ raise UnsupportedOperation(self._unsupported_msg('absolute()'))
+ else:
+ # Treat the root directory as the current working directory.
+ return self.with_segments('/', *self._raw_paths)
@classmethod
def cwd(cls):
@@ -772,10 +778,13 @@ class PathBase(PurePathBase):
"""
if self._resolving:
return self
+ elif self.parser is not posixpath:
+ raise UnsupportedOperation(self._unsupported_msg('resolve()'))
- def getcwd():
- return str(self.with_segments().absolute())
+ def raise_error(*args):
+ raise OSError("Unsupported operation.")
+ getcwd = raise_error
if strict or getattr(self.readlink, '_supported', True):
def lstat(path_str):
path = self.with_segments(path_str)
@@ -790,14 +799,10 @@ class PathBase(PurePathBase):
# If the user has *not* overridden the `readlink()` method, then
# symlinks are unsupported and (in non-strict mode) we can improve
# performance by not calling `path.lstat()`.
- def skip(path_str):
- # This exception will be internally consumed by `_realpath()`.
- raise OSError("Operation skipped.")
-
- lstat = readlink = skip
+ lstat = readlink = raise_error
return self.with_segments(posixpath._realpath(
- str(self), strict, self.parser.sep,
+ str(self.absolute()), strict, self.parser.sep,
getcwd=getcwd, lstat=lstat, readlink=readlink,
maxlinks=self._max_symlinks))