]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
GH-114610: Fix `pathlib.PurePath.with_stem('')` handling of file extensions (#114612)
authorBarney Gale <barney.gale@gmail.com>
Sat, 24 Feb 2024 19:37:03 +0000 (19:37 +0000)
committerGitHub <noreply@github.com>
Sat, 24 Feb 2024 19:37:03 +0000 (19:37 +0000)
Raise `ValueError` if `with_stem('')` is called on a path with a file
extension. Paths may only have an empty stem if they also have an empty
suffix.

Lib/pathlib/_abc.py
Lib/test/test_pathlib/test_pathlib_abc.py
Misc/NEWS.d/next/Library/2024-01-26-16-42-31.gh-issue-114610.S18Vuz.rst [new file with mode: 0644]

index 27c6b4e367a050f6ddabb5af1a9aac941d1782ba..44fea525b6cac747e3670f4a0a242b7d65d8e4b0 100644 (file)
@@ -313,7 +313,14 @@ class PurePathBase:
 
     def with_stem(self, stem):
         """Return a new path with the stem changed."""
-        return self.with_name(stem + self.suffix)
+        suffix = self.suffix
+        if not suffix:
+            return self.with_name(stem)
+        elif not stem:
+            # If the suffix is non-empty, we can't make the stem empty.
+            raise ValueError(f"{self!r} has a non-empty suffix")
+        else:
+            return self.with_name(stem + suffix)
 
     def with_suffix(self, suffix):
         """Return a new path with the file suffix changed.  If the path
@@ -324,6 +331,7 @@ class PurePathBase:
         if not suffix:
             return self.with_name(stem)
         elif not stem:
+            # If the stem is empty, we can't make the suffix non-empty.
             raise ValueError(f"{self!r} has an empty name")
         elif suffix.startswith('.') and len(suffix) > 1:
             return self.with_name(stem + suffix)
index 1d30deca8f7a1bbe0234f779199fc2228a6decde..5bfb76f85c79094566b1606c3b161d31c982eb55 100644 (file)
@@ -957,6 +957,8 @@ class DummyPurePathTest(unittest.TestCase):
         self.assertEqual(P('/').with_stem('d'), P('/d'))
         self.assertEqual(P('a/b').with_stem(''), P('a/'))
         self.assertEqual(P('a/b').with_stem('.'), P('a/.'))
+        self.assertRaises(ValueError, P('foo.gz').with_stem, '')
+        self.assertRaises(ValueError, P('/a/b/foo.gz').with_stem, '')
 
     def test_with_stem_seps(self):
         P = self.cls
diff --git a/Misc/NEWS.d/next/Library/2024-01-26-16-42-31.gh-issue-114610.S18Vuz.rst b/Misc/NEWS.d/next/Library/2024-01-26-16-42-31.gh-issue-114610.S18Vuz.rst
new file mode 100644 (file)
index 0000000..519aede
--- /dev/null
@@ -0,0 +1,4 @@
+Fix bug where :meth:`pathlib.PurePath.with_stem` converted a non-empty path
+suffix to a stem when given an empty *stem* argument. It now raises
+:exc:`ValueError`, just like :meth:`pathlib.PurePath.with_suffix` does when
+called on a path with an empty stem, given a non-empty *suffix* argument.