From 06b0c740e9f7adeefc4764d9f5a1a59d5a5c2331 Mon Sep 17 00:00:00 2001 From: barneygale Date: Sat, 15 May 2021 23:00:51 +0100 Subject: [PATCH 1/9] bpo-29688: document and test `pathlib.Path.absolute()`. --- Doc/library/pathlib.rst | 21 ++++++++++++++++++--- Lib/pathlib.py | 11 +++-------- Lib/test/test_pathlib.py | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 11 deletions(-) diff --git a/Doc/library/pathlib.rst b/Doc/library/pathlib.rst index b6507eb4d6fa2c..690f1e98b874c9 100644 --- a/Doc/library/pathlib.rst +++ b/Doc/library/pathlib.rst @@ -1052,6 +1052,20 @@ call fails (for example because the path doesn't exist). Added return value, return the new Path instance. +.. method:: Path.absolute() + + Make the path absolute, without resolving symlinks, and return a new path + object. This is equivalent to prepending the current directory:: + + >>> p = Path('..') + >>> p + PosixPath('..') + >>> p.absolute() + PosixPath('/home/antoine/pathlib/..') + >>> Path.cwd() / p + PosixPath('/home/antoine/pathlib/..') + + .. method:: Path.resolve(strict=False) Make the path absolute, resolving any symlinks. A new path object is @@ -1239,13 +1253,14 @@ Below is a table mapping various :mod:`os` functions to their corresponding Not all pairs of functions/methods below are equivalent. Some of them, despite having some overlapping use-cases, have different semantics. They - include :func:`os.path.abspath` and :meth:`Path.resolve`, + include :func:`os.path.abspath` and :meth:`Path.absolute`, :func:`os.path.relpath` and :meth:`PurePath.relative_to`. ==================================== ============================== :mod:`os` and :mod:`os.path` :mod:`pathlib` ==================================== ============================== -:func:`os.path.abspath` :meth:`Path.resolve` [#]_ +:func:`os.path.abspath` :meth:`Path.absolute` [#]_ +:func:`os.path.realpath` :meth:`Path.resolve` :func:`os.chmod` :meth:`Path.chmod` :func:`os.mkdir` :meth:`Path.mkdir` :func:`os.makedirs` :meth:`Path.mkdir` @@ -1278,5 +1293,5 @@ Below is a table mapping various :mod:`os` functions to their corresponding .. rubric:: Footnotes -.. [#] :func:`os.path.abspath` does not resolve symbolic links while :meth:`Path.resolve` does. +.. [#] :func:`os.path.abspath` normalizes the resulting path, which may change its meaning in the presence of symlinks. .. [#] :meth:`Path.relative_to` requires ``self`` to be the subpath of the argument, but :func:`os.path.relpath` does not. diff --git a/Lib/pathlib.py b/Lib/pathlib.py index f1a33178e2958b..8caa7c02ee80c4 100644 --- a/Lib/pathlib.py +++ b/Lib/pathlib.py @@ -1046,24 +1046,19 @@ def rglob(self, pattern): yield p def absolute(self): - """Return an absolute version of this path. This function works - even if the path doesn't point to anything. + """Return an absolute version of this path by prepending the current + working directory. No normalization or symlink resolution is performed. - No normalization is done, i.e. all '.' and '..' will be kept along. Use resolve() to get the canonical path to a file. """ - # XXX untested yet! if self.is_absolute(): return self - # FIXME this must defer to the specific flavour (and, under Windows, - # use nt._getfullpathname()) return self._from_parts([self._accessor.getcwd()] + self._parts) def resolve(self, strict=False): """ Make the path absolute, resolving all symlinks on the way and also - normalizing it (for example turning slashes into backslashes under - Windows). + normalizing it. """ def check_eloop(e): diff --git a/Lib/test/test_pathlib.py b/Lib/test/test_pathlib.py index 555c7ee795bd12..9443e71bdf489b 100644 --- a/Lib/test/test_pathlib.py +++ b/Lib/test/test_pathlib.py @@ -1456,6 +1456,39 @@ def test_cwd(self): p = self.cls.cwd() self._test_cwd(p) + def _test_absolute(self): + P = self.cls + + # Simple absolute paths + self.assertEqualNormCase(str(P('/').absolute()), '/') + self.assertEqualNormCase(str(P('/a').absolute()), '/a') + self.assertEqualNormCase(str(P('/a/b').absolute()), '/a/b') + self.assertEqualNormCase(str(P('//a/b').absolute()), '//a/b') + + # Simple relative paths + self.assertEqualNormCase(str(P().absolute()), BASE) + self.assertEqualNormCase(str(P('.').absolute()), BASE) + self.assertEqualNormCase(str(P('a').absolute()), os.path.join(BASE, 'a')) + self.assertEqualNormCase(str(P('a', 'b', 'c').absolute()), os.path.join(BASE, 'a', 'b', 'c')) + + # Symlinks should not be resolved + self.assertEqualNormCase(str(P('linkB', 'fileB').absolute()), os.path.join(BASE, 'linkB', 'fileB')) + self.assertEqualNormCase(str(P('brokenLink').absolute()), os.path.join(BASE, 'brokenLink')) + self.assertEqualNormCase(str(P('brokenLinkLoop').absolute()), os.path.join(BASE, 'brokenLinkLoop')) + + # '..' entries should be preserved and not normalised + self.assertEqualNormCase(str(P('..').absolute()), os.path.join(BASE, '..')) + self.assertEqualNormCase(str(P('a', '..').absolute()), os.path.join(BASE, 'a', '..')) + self.assertEqualNormCase(str(P('..', 'b').absolute()), os.path.join(BASE, '..', 'b')) + + def test_absolute(self): + old_path = os.getcwd() + os.chdir(BASE) + try: + self._test_absolute() + finally: + os.chdir(old_path) + def _test_home(self, p): q = self.cls(os.path.expanduser('~')) self.assertEqual(p, q) From b5ff1e60e8d8eef2dd51199a926b96f30359cea6 Mon Sep 17 00:00:00 2001 From: barneygale Date: Sun, 16 May 2021 20:56:10 +0100 Subject: [PATCH 2/9] Add tests for UNC paths. --- Lib/test/test_pathlib.py | 82 +++++++++++++++++++++++++++------------- 1 file changed, 55 insertions(+), 27 deletions(-) diff --git a/Lib/test/test_pathlib.py b/Lib/test/test_pathlib.py index 9443e71bdf489b..70d18162f91c37 100644 --- a/Lib/test/test_pathlib.py +++ b/Lib/test/test_pathlib.py @@ -1456,38 +1456,27 @@ def test_cwd(self): p = self.cls.cwd() self._test_cwd(p) - def _test_absolute(self): + def test_absolute_common(self): P = self.cls - # Simple absolute paths - self.assertEqualNormCase(str(P('/').absolute()), '/') - self.assertEqualNormCase(str(P('/a').absolute()), '/a') - self.assertEqualNormCase(str(P('/a/b').absolute()), '/a/b') - self.assertEqualNormCase(str(P('//a/b').absolute()), '//a/b') + with mock.patch("pathlib._normal_accessor.getcwd") as getcwd: + getcwd.return_value = BASE - # Simple relative paths - self.assertEqualNormCase(str(P().absolute()), BASE) - self.assertEqualNormCase(str(P('.').absolute()), BASE) - self.assertEqualNormCase(str(P('a').absolute()), os.path.join(BASE, 'a')) - self.assertEqualNormCase(str(P('a', 'b', 'c').absolute()), os.path.join(BASE, 'a', 'b', 'c')) + # Simple relative paths + self.assertEqualNormCase(str(P().absolute()), BASE) + self.assertEqualNormCase(str(P('.').absolute()), BASE) + self.assertEqualNormCase(str(P('a').absolute()), os.path.join(BASE, 'a')) + self.assertEqualNormCase(str(P('a', 'b', 'c').absolute()), os.path.join(BASE, 'a', 'b', 'c')) - # Symlinks should not be resolved - self.assertEqualNormCase(str(P('linkB', 'fileB').absolute()), os.path.join(BASE, 'linkB', 'fileB')) - self.assertEqualNormCase(str(P('brokenLink').absolute()), os.path.join(BASE, 'brokenLink')) - self.assertEqualNormCase(str(P('brokenLinkLoop').absolute()), os.path.join(BASE, 'brokenLinkLoop')) + # Symlinks should not be resolved + self.assertEqualNormCase(str(P('linkB', 'fileB').absolute()), os.path.join(BASE, 'linkB', 'fileB')) + self.assertEqualNormCase(str(P('brokenLink').absolute()), os.path.join(BASE, 'brokenLink')) + self.assertEqualNormCase(str(P('brokenLinkLoop').absolute()), os.path.join(BASE, 'brokenLinkLoop')) - # '..' entries should be preserved and not normalised - self.assertEqualNormCase(str(P('..').absolute()), os.path.join(BASE, '..')) - self.assertEqualNormCase(str(P('a', '..').absolute()), os.path.join(BASE, 'a', '..')) - self.assertEqualNormCase(str(P('..', 'b').absolute()), os.path.join(BASE, '..', 'b')) - - def test_absolute(self): - old_path = os.getcwd() - os.chdir(BASE) - try: - self._test_absolute() - finally: - os.chdir(old_path) + # '..' entries should be preserved and not normalised + self.assertEqualNormCase(str(P('..').absolute()), os.path.join(BASE, '..')) + self.assertEqualNormCase(str(P('a', '..').absolute()), os.path.join(BASE, 'a', '..')) + self.assertEqualNormCase(str(P('..', 'b').absolute()), os.path.join(BASE, '..', 'b')) def _test_home(self, p): q = self.cls(os.path.expanduser('~')) @@ -2490,6 +2479,17 @@ def test_glob_empty_pattern(self): class PosixPathTest(_BasePathTest, unittest.TestCase): cls = pathlib.PosixPath + def test_absolute(self): + P = self.cls + self.assertEqualNormCase(str(P('/').absolute()), '/') + self.assertEqualNormCase(str(P('/a').absolute()), '/a') + self.assertEqualNormCase(str(P('/a/b').absolute()), '/a/b') + + # '//'-prefixed absolute path (supported by POSIX) + self.assertEqualNormCase(str(P('//').absolute()), '//') + self.assertEqualNormCase(str(P('//a').absolute()), '//a') + self.assertEqualNormCase(str(P('//a/b').absolute()), '//a/b') + def _check_symlink_loop(self, *args, strict=True): path = self.cls(*args) with self.assertRaises(RuntimeError): @@ -2655,6 +2655,34 @@ def test_handling_bad_descriptor(self): class WindowsPathTest(_BasePathTest, unittest.TestCase): cls = pathlib.WindowsPath + def test_absolute(self): + P = self.cls + + # Simple absolute paths + self.assertEqualNormCase(str(P('c:\\').absolute()), 'c:\\') + self.assertEqualNormCase(str(P('c:\\a').absolute()), 'c:\\a') + self.assertEqualNormCase(str(P('c:\\a\\b').absolute()), 'c:\\a\\b') + + # UNC absolute paths + share = '\\\\server\\share' + self.assertEqualNormCase(str(P(share).absolute()), share) + self.assertEqualNormCase(str(P(share + '\\a').absolute()), + share + '\\a') + self.assertEqualNormCase(str(P(share + '\\a\\b').absolute()), + share + '\\a\\b') + + # UNC relative paths + with mock.patch("pathlib._normal_accessor.getcwd") as getcwd: + getcwd.return_value = share + + self.assertEqualNormCase(str(P().absolute()), BASE) + self.assertEqualNormCase(str(P('.').absolute()), BASE) + self.assertEqualNormCase(str(P('a').absolute()), + os.path.join(BASE, 'a')) + self.assertEqualNormCase(str(P('a', 'b', 'c').absolute()), + os.path.join(BASE, 'a', 'b', 'c')) + + def test_glob(self): P = self.cls p = P(BASE) From 8695087e57d9cbd17ed36824f80b988b19adc18e Mon Sep 17 00:00:00 2001 From: barneygale Date: Sun, 16 May 2021 21:39:28 +0100 Subject: [PATCH 3/9] Fix Windows tests (attempt 1) --- Lib/test/test_pathlib.py | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/Lib/test/test_pathlib.py b/Lib/test/test_pathlib.py index 70d18162f91c37..75d2c71747c243 100644 --- a/Lib/test/test_pathlib.py +++ b/Lib/test/test_pathlib.py @@ -2664,23 +2664,21 @@ def test_absolute(self): self.assertEqualNormCase(str(P('c:\\a\\b').absolute()), 'c:\\a\\b') # UNC absolute paths - share = '\\\\server\\share' + share = '\\\\server\\share\\' self.assertEqualNormCase(str(P(share).absolute()), share) - self.assertEqualNormCase(str(P(share + '\\a').absolute()), - share + '\\a') - self.assertEqualNormCase(str(P(share + '\\a\\b').absolute()), - share + '\\a\\b') + self.assertEqualNormCase(str(P(share + 'a').absolute()), share + 'a') + self.assertEqualNormCase(str(P(share + 'a\\b').absolute()), share + 'a\\b') # UNC relative paths with mock.patch("pathlib._normal_accessor.getcwd") as getcwd: getcwd.return_value = share - self.assertEqualNormCase(str(P().absolute()), BASE) - self.assertEqualNormCase(str(P('.').absolute()), BASE) + self.assertEqualNormCase(str(P().absolute()), share) + self.assertEqualNormCase(str(P('.').absolute()), share) self.assertEqualNormCase(str(P('a').absolute()), - os.path.join(BASE, 'a')) + os.path.join(share, 'a')) self.assertEqualNormCase(str(P('a', 'b', 'c').absolute()), - os.path.join(BASE, 'a', 'b', 'c')) + os.path.join(share, 'a', 'b', 'c')) def test_glob(self): From 5539824ece93f29df8a57ab7c0e38cedf72b8fc9 Mon Sep 17 00:00:00 2001 From: barneygale Date: Sun, 16 May 2021 23:27:14 +0100 Subject: [PATCH 4/9] `assertEqualNormCase()` --> `assertEqual()` --- Lib/test/test_pathlib.py | 55 ++++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 28 deletions(-) diff --git a/Lib/test/test_pathlib.py b/Lib/test/test_pathlib.py index 75d2c71747c243..0b6e3707855157 100644 --- a/Lib/test/test_pathlib.py +++ b/Lib/test/test_pathlib.py @@ -1463,20 +1463,20 @@ def test_absolute_common(self): getcwd.return_value = BASE # Simple relative paths - self.assertEqualNormCase(str(P().absolute()), BASE) - self.assertEqualNormCase(str(P('.').absolute()), BASE) - self.assertEqualNormCase(str(P('a').absolute()), os.path.join(BASE, 'a')) - self.assertEqualNormCase(str(P('a', 'b', 'c').absolute()), os.path.join(BASE, 'a', 'b', 'c')) + self.assertEqual(str(P().absolute()), BASE) + self.assertEqual(str(P('.').absolute()), BASE) + self.assertEqual(str(P('a').absolute()), os.path.join(BASE, 'a')) + self.assertEqual(str(P('a', 'b', 'c').absolute()), os.path.join(BASE, 'a', 'b', 'c')) # Symlinks should not be resolved - self.assertEqualNormCase(str(P('linkB', 'fileB').absolute()), os.path.join(BASE, 'linkB', 'fileB')) - self.assertEqualNormCase(str(P('brokenLink').absolute()), os.path.join(BASE, 'brokenLink')) - self.assertEqualNormCase(str(P('brokenLinkLoop').absolute()), os.path.join(BASE, 'brokenLinkLoop')) + self.assertEqual(str(P('linkB', 'fileB').absolute()), os.path.join(BASE, 'linkB', 'fileB')) + self.assertEqual(str(P('brokenLink').absolute()), os.path.join(BASE, 'brokenLink')) + self.assertEqual(str(P('brokenLinkLoop').absolute()), os.path.join(BASE, 'brokenLinkLoop')) # '..' entries should be preserved and not normalised - self.assertEqualNormCase(str(P('..').absolute()), os.path.join(BASE, '..')) - self.assertEqualNormCase(str(P('a', '..').absolute()), os.path.join(BASE, 'a', '..')) - self.assertEqualNormCase(str(P('..', 'b').absolute()), os.path.join(BASE, '..', 'b')) + self.assertEqual(str(P('..').absolute()), os.path.join(BASE, '..')) + self.assertEqual(str(P('a', '..').absolute()), os.path.join(BASE, 'a', '..')) + self.assertEqual(str(P('..', 'b').absolute()), os.path.join(BASE, '..', 'b')) def _test_home(self, p): q = self.cls(os.path.expanduser('~')) @@ -2481,14 +2481,14 @@ class PosixPathTest(_BasePathTest, unittest.TestCase): def test_absolute(self): P = self.cls - self.assertEqualNormCase(str(P('/').absolute()), '/') - self.assertEqualNormCase(str(P('/a').absolute()), '/a') - self.assertEqualNormCase(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.assertEqualNormCase(str(P('//').absolute()), '//') - self.assertEqualNormCase(str(P('//a').absolute()), '//a') - self.assertEqualNormCase(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') def _check_symlink_loop(self, *args, strict=True): path = self.cls(*args) @@ -2659,26 +2659,25 @@ def test_absolute(self): P = self.cls # Simple absolute paths - self.assertEqualNormCase(str(P('c:\\').absolute()), 'c:\\') - self.assertEqualNormCase(str(P('c:\\a').absolute()), 'c:\\a') - self.assertEqualNormCase(str(P('c:\\a\\b').absolute()), 'c:\\a\\b') + self.assertEqual(str(P('c:\\').absolute()), 'c:\\') + self.assertEqual(str(P('c:\\a').absolute()), 'c:\\a') + self.assertEqual(str(P('c:\\a\\b').absolute()), 'c:\\a\\b') # UNC absolute paths share = '\\\\server\\share\\' - self.assertEqualNormCase(str(P(share).absolute()), share) - self.assertEqualNormCase(str(P(share + 'a').absolute()), share + 'a') - self.assertEqualNormCase(str(P(share + 'a\\b').absolute()), share + 'a\\b') + self.assertEqual(str(P(share).absolute()), share) + self.assertEqual(str(P(share + 'a').absolute()), share + 'a') + self.assertEqual(str(P(share + 'a\\b').absolute()), share + 'a\\b') # UNC relative paths with mock.patch("pathlib._normal_accessor.getcwd") as getcwd: getcwd.return_value = share - self.assertEqualNormCase(str(P().absolute()), share) - self.assertEqualNormCase(str(P('.').absolute()), share) - self.assertEqualNormCase(str(P('a').absolute()), - os.path.join(share, 'a')) - self.assertEqualNormCase(str(P('a', 'b', 'c').absolute()), - os.path.join(share, 'a', 'b', 'c')) + self.assertEqual(str(P().absolute()), share) + self.assertEqual(str(P('.').absolute()), share) + self.assertEqual(str(P('a').absolute()), os.path.join(share, 'a')) + self.assertEqual(str(P('a', 'b', 'c').absolute()), + os.path.join(share, 'a', 'b', 'c')) def test_glob(self): From 7cd4fff08838e274e1696661aa8ab54c3bec7440 Mon Sep 17 00:00:00 2001 From: Barney Gale Date: Sat, 1 Jan 2022 01:05:53 +0000 Subject: [PATCH 5/9] Update Doc/library/pathlib.rst Co-authored-by: Brett Cannon --- Doc/library/pathlib.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/pathlib.rst b/Doc/library/pathlib.rst index 690f1e98b874c9..503f63486fe484 100644 --- a/Doc/library/pathlib.rst +++ b/Doc/library/pathlib.rst @@ -1054,7 +1054,7 @@ call fails (for example because the path doesn't exist). .. method:: Path.absolute() - Make the path absolute, without resolving symlinks, and return a new path + Make the path absolute, without normalization or resolving symlinks, and return a new path object. This is equivalent to prepending the current directory:: >>> p = Path('..') From 64204fd34f020b13589f341e12964df430545b5f Mon Sep 17 00:00:00 2001 From: Barney Gale Date: Sat, 1 Jan 2022 01:06:23 +0000 Subject: [PATCH 6/9] Update Doc/library/pathlib.rst Co-authored-by: Brian Helba --- Doc/library/pathlib.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/pathlib.rst b/Doc/library/pathlib.rst index 503f63486fe484..06f032c6887fa9 100644 --- a/Doc/library/pathlib.rst +++ b/Doc/library/pathlib.rst @@ -1293,5 +1293,5 @@ Below is a table mapping various :mod:`os` functions to their corresponding .. rubric:: Footnotes -.. [#] :func:`os.path.abspath` normalizes the resulting path, which may change its meaning in the presence of symlinks. +.. [#] :func:`os.path.abspath` normalizes the resulting path, which may change its meaning in the presence of symlinks, while :meth:`Path.absolute` does not. .. [#] :meth:`Path.relative_to` requires ``self`` to be the subpath of the argument, but :func:`os.path.relpath` does not. From b2bf3dad776831e4d3e6f38576839b833faae95e Mon Sep 17 00:00:00 2001 From: barneygale Date: Wed, 5 Jan 2022 03:21:24 +0000 Subject: [PATCH 7/9] Add news entry. --- .../next/Library/2022-01-05-03-21-21.bpo-29688.W06bSH.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2022-01-05-03-21-21.bpo-29688.W06bSH.rst diff --git a/Misc/NEWS.d/next/Library/2022-01-05-03-21-21.bpo-29688.W06bSH.rst b/Misc/NEWS.d/next/Library/2022-01-05-03-21-21.bpo-29688.W06bSH.rst new file mode 100644 index 00000000000000..ac8b1e0b0ebaba --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-01-05-03-21-21.bpo-29688.W06bSH.rst @@ -0,0 +1,2 @@ +:meth:`pathlib.Path.absolute` is now documented. This method has always been +present in pathlib. From 2a9ebd04cf4197e73b130ea78c93112717ac51e2 Mon Sep 17 00:00:00 2001 From: Barney Gale Date: Sat, 8 Jan 2022 20:37:50 +0000 Subject: [PATCH 8/9] Apply suggestions from code review Co-authored-by: Brett Cannon --- Lib/test/test_pathlib.py | 14 +++++++------- .../2022-01-05-03-21-21.bpo-29688.W06bSH.rst | 3 +-- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/Lib/test/test_pathlib.py b/Lib/test/test_pathlib.py index 0b6e3707855157..d004c38211c48e 100644 --- a/Lib/test/test_pathlib.py +++ b/Lib/test/test_pathlib.py @@ -1462,18 +1462,18 @@ def test_absolute_common(self): with mock.patch("pathlib._normal_accessor.getcwd") as getcwd: getcwd.return_value = BASE - # Simple relative paths + # Simple relative paths. self.assertEqual(str(P().absolute()), BASE) self.assertEqual(str(P('.').absolute()), BASE) self.assertEqual(str(P('a').absolute()), os.path.join(BASE, 'a')) self.assertEqual(str(P('a', 'b', 'c').absolute()), os.path.join(BASE, 'a', 'b', 'c')) - # Symlinks should not be resolved + # Symlinks should not be resolved. self.assertEqual(str(P('linkB', 'fileB').absolute()), os.path.join(BASE, 'linkB', 'fileB')) self.assertEqual(str(P('brokenLink').absolute()), os.path.join(BASE, 'brokenLink')) self.assertEqual(str(P('brokenLinkLoop').absolute()), os.path.join(BASE, 'brokenLinkLoop')) - # '..' entries should be preserved and not normalised + # '..' entries should be preserved and not normalised. self.assertEqual(str(P('..').absolute()), os.path.join(BASE, '..')) self.assertEqual(str(P('a', '..').absolute()), os.path.join(BASE, 'a', '..')) self.assertEqual(str(P('..', 'b').absolute()), os.path.join(BASE, '..', 'b')) @@ -2485,7 +2485,7 @@ def test_absolute(self): self.assertEqual(str(P('/a').absolute()), '/a') self.assertEqual(str(P('/a/b').absolute()), '/a/b') - # '//'-prefixed absolute path (supported by POSIX) + # '//'-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') @@ -2658,18 +2658,18 @@ class WindowsPathTest(_BasePathTest, unittest.TestCase): def test_absolute(self): P = self.cls - # Simple absolute paths + # Simple absolute paths. self.assertEqual(str(P('c:\\').absolute()), 'c:\\') self.assertEqual(str(P('c:\\a').absolute()), 'c:\\a') self.assertEqual(str(P('c:\\a\\b').absolute()), 'c:\\a\\b') - # UNC absolute paths + # UNC absolute paths. share = '\\\\server\\share\\' self.assertEqual(str(P(share).absolute()), share) self.assertEqual(str(P(share + 'a').absolute()), share + 'a') self.assertEqual(str(P(share + 'a\\b').absolute()), share + 'a\\b') - # UNC relative paths + # UNC relative paths. with mock.patch("pathlib._normal_accessor.getcwd") as getcwd: getcwd.return_value = share diff --git a/Misc/NEWS.d/next/Library/2022-01-05-03-21-21.bpo-29688.W06bSH.rst b/Misc/NEWS.d/next/Library/2022-01-05-03-21-21.bpo-29688.W06bSH.rst index ac8b1e0b0ebaba..1a202e59b075e7 100644 --- a/Misc/NEWS.d/next/Library/2022-01-05-03-21-21.bpo-29688.W06bSH.rst +++ b/Misc/NEWS.d/next/Library/2022-01-05-03-21-21.bpo-29688.W06bSH.rst @@ -1,2 +1 @@ -:meth:`pathlib.Path.absolute` is now documented. This method has always been -present in pathlib. +Document :meth:`pathlib.Path.absolute` (which has always existed). From 51aa187aaf08e7713d7a79d28431d94cc8295246 Mon Sep 17 00:00:00 2001 From: barneygale Date: Tue, 11 Jan 2022 22:50:40 +0000 Subject: [PATCH 9/9] Remove example in docs showing that `..` entries are retained. --- Doc/library/pathlib.rst | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/Doc/library/pathlib.rst b/Doc/library/pathlib.rst index 06f032c6887fa9..7ab603fd133b86 100644 --- a/Doc/library/pathlib.rst +++ b/Doc/library/pathlib.rst @@ -1054,16 +1054,14 @@ call fails (for example because the path doesn't exist). .. method:: Path.absolute() - Make the path absolute, without normalization or resolving symlinks, and return a new path - object. This is equivalent to prepending the current directory:: + Make the path absolute, without normalization or resolving symlinks. + Returns a new path object:: - >>> p = Path('..') + >>> p = Path('tests') >>> p - PosixPath('..') + PosixPath('tests') >>> p.absolute() - PosixPath('/home/antoine/pathlib/..') - >>> Path.cwd() / p - PosixPath('/home/antoine/pathlib/..') + PosixPath('/home/antoine/pathlib/tests') .. method:: Path.resolve(strict=False) pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy