summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Lib/pathlib/_abc.py23
-rw-r--r--Lib/test/test_pathlib/test_pathlib.py22
-rw-r--r--Lib/test/test_pathlib/test_pathlib_abc.py40
3 files changed, 53 insertions, 32 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))
diff --git a/Lib/test/test_pathlib/test_pathlib.py b/Lib/test/test_pathlib/test_pathlib.py
index c7104bf..46966b6 100644
--- a/Lib/test/test_pathlib/test_pathlib.py
+++ b/Lib/test/test_pathlib/test_pathlib.py
@@ -861,6 +861,28 @@ class PathTest(test_pathlib_abc.DummyPathTest, PurePathTest):
def test_move_into_empty_name_other_os(self):
self.test_move_into_empty_name()
+ def _check_complex_symlinks(self, link0_target):
+ super()._check_complex_symlinks(link0_target)
+ P = self.cls(self.base)
+ # Resolve relative paths.
+ old_path = os.getcwd()
+ os.chdir(self.base)
+ try:
+ p = self.cls('link0').resolve()
+ self.assertEqual(p, P)
+ self.assertEqualNormCase(str(p), self.base)
+ p = self.cls('link1').resolve()
+ self.assertEqual(p, P)
+ self.assertEqualNormCase(str(p), self.base)
+ p = self.cls('link2').resolve()
+ self.assertEqual(p, P)
+ self.assertEqualNormCase(str(p), self.base)
+ p = self.cls('link3').resolve()
+ self.assertEqual(p, P)
+ self.assertEqualNormCase(str(p), self.base)
+ finally:
+ os.chdir(old_path)
+
def test_resolve_nonexist_relative_issue38671(self):
p = self.cls('non', 'exist')
diff --git a/Lib/test/test_pathlib/test_pathlib_abc.py b/Lib/test/test_pathlib/test_pathlib_abc.py
index bb2e418..b69d674 100644
--- a/Lib/test/test_pathlib/test_pathlib_abc.py
+++ b/Lib/test/test_pathlib/test_pathlib_abc.py
@@ -2493,6 +2493,23 @@ class DummyPathTest(DummyPurePathTest):
bad_link.symlink_to("bad" * 200)
self.assertEqual(sorted(base.glob('**/*')), [bad_link])
+ @needs_posix
+ def test_absolute_posix(self):
+ P = self.cls
+ # The default implementation uses '/' as the current directory
+ self.assertEqual(str(P('').absolute()), '/')
+ self.assertEqual(str(P('a').absolute()), '/a')
+ self.assertEqual(str(P('a/b').absolute()), '/a/b')
+
+ self.assertEqual(str(P('/').absolute()), '/')
+ self.assertEqual(str(P('/a').absolute()), '/a')
+ self.assertEqual(str(P('/a/b').absolute()), '/a/b')
+
+ # '//'-prefixed absolute path (supported by POSIX).
+ self.assertEqual(str(P('//').absolute()), '//')
+ self.assertEqual(str(P('//a').absolute()), '//a')
+ self.assertEqual(str(P('//a/b').absolute()), '//a/b')
+
@needs_symlinks
def test_readlink(self):
P = self.cls(self.base)
@@ -2810,29 +2827,6 @@ class DummyPathTest(DummyPurePathTest):
self.assertEqual(p, P)
self.assertEqualNormCase(str(p), self.base)
- # Resolve relative paths.
- try:
- self.cls('').absolute()
- except UnsupportedOperation:
- return
- old_path = os.getcwd()
- os.chdir(self.base)
- try:
- p = self.cls('link0').resolve()
- self.assertEqual(p, P)
- self.assertEqualNormCase(str(p), self.base)
- p = self.cls('link1').resolve()
- self.assertEqual(p, P)
- self.assertEqualNormCase(str(p), self.base)
- p = self.cls('link2').resolve()
- self.assertEqual(p, P)
- self.assertEqualNormCase(str(p), self.base)
- p = self.cls('link3').resolve()
- self.assertEqual(p, P)
- self.assertEqualNormCase(str(p), self.base)
- finally:
- os.chdir(old_path)
-
@needs_symlinks
def test_complex_symlinks_absolute(self):
self._check_complex_symlinks(self.base)