GH-114610: Fix `pathlib.PurePath.with_stem('')` handling of file extensions (#114612)

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.
This commit is contained in:
Barney Gale 2024-02-24 19:37:03 +00:00 committed by GitHub
parent 53c5c17e0a
commit e3dedeae7a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 15 additions and 1 deletions

View 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)

View 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

View File

@ -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.