Skip to content

Commit e3dedea

Browse files
authored
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.
1 parent 53c5c17 commit e3dedea

File tree

3 files changed

+15
-1
lines changed

3 files changed

+15
-1
lines changed

Lib/pathlib/_abc.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,14 @@ def with_name(self, name):
313313

314314
def with_stem(self, stem):
315315
"""Return a new path with the stem changed."""
316-
return self.with_name(stem + self.suffix)
316+
suffix = self.suffix
317+
if not suffix:
318+
return self.with_name(stem)
319+
elif not stem:
320+
# If the suffix is non-empty, we can't make the stem empty.
321+
raise ValueError(f"{self!r} has a non-empty suffix")
322+
else:
323+
return self.with_name(stem + suffix)
317324

318325
def with_suffix(self, suffix):
319326
"""Return a new path with the file suffix changed. If the path
@@ -324,6 +331,7 @@ def with_suffix(self, suffix):
324331
if not suffix:
325332
return self.with_name(stem)
326333
elif not stem:
334+
# If the stem is empty, we can't make the suffix non-empty.
327335
raise ValueError(f"{self!r} has an empty name")
328336
elif suffix.startswith('.') and len(suffix) > 1:
329337
return self.with_name(stem + suffix)

Lib/test/test_pathlib/test_pathlib_abc.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -957,6 +957,8 @@ def test_with_stem_empty(self):
957957
self.assertEqual(P('/').with_stem('d'), P('/d'))
958958
self.assertEqual(P('a/b').with_stem(''), P('a/'))
959959
self.assertEqual(P('a/b').with_stem('.'), P('a/.'))
960+
self.assertRaises(ValueError, P('foo.gz').with_stem, '')
961+
self.assertRaises(ValueError, P('/a/b/foo.gz').with_stem, '')
960962

961963
def test_with_stem_seps(self):
962964
P = self.cls
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Fix bug where :meth:`pathlib.PurePath.with_stem` converted a non-empty path
2+
suffix to a stem when given an empty *stem* argument. It now raises
3+
:exc:`ValueError`, just like :meth:`pathlib.PurePath.with_suffix` does when
4+
called on a path with an empty stem, given a non-empty *suffix* argument.

0 commit comments

Comments
 (0)