Skip to content

Commit

Permalink
pythonGH-128520: pathlib ABCs: fix with_name() handling of empty names
Browse files Browse the repository at this point in the history
Raise `ValueError` from `pathlib.types._JoinablePath.with_name()` when
given an empty name, or acting upon a path with an empty name. This
behaviour matches `pathlib.PurePath.with_name()`.
  • Loading branch information
barneygale committed Mar 7, 2025
1 parent 3dd3675 commit 1130cc5
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 16 deletions.
7 changes: 5 additions & 2 deletions Lib/pathlib/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,12 @@ def stem(self):
def with_name(self, name):
"""Return a new path with the file name changed."""
split = self.parser.split
if split(name)[0]:
if not name or split(name)[0]:
raise ValueError(f"Invalid name {name!r}")
return self.with_segments(split(str(self))[0], name)
parent, old_name = split(str(self))
if not old_name:
raise ValueError(f"{self!r} has an empty name")
return self.with_segments(parent, name)

def with_stem(self, stem):
"""Return a new path with the stem changed."""
Expand Down
6 changes: 0 additions & 6 deletions Lib/test/test_pathlib/test_pathlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -413,18 +413,12 @@ def test_stem_empty(self):

def test_with_name_empty(self):
P = self.cls
self.assertRaises(ValueError, P('').with_name, 'd.xml')
self.assertRaises(ValueError, P('.').with_name, 'd.xml')
self.assertRaises(ValueError, P('/').with_name, 'd.xml')
self.assertRaises(ValueError, P('a/b').with_name, '')
self.assertRaises(ValueError, P('a/b').with_name, '.')

def test_with_stem_empty(self):
P = self.cls
self.assertRaises(ValueError, P('').with_stem, 'd')
self.assertRaises(ValueError, P('.').with_stem, 'd')
self.assertRaises(ValueError, P('/').with_stem, 'd')
self.assertRaises(ValueError, P('a/b').with_stem, '')
self.assertRaises(ValueError, P('a/b').with_stem, '.')

def test_is_reserved_deprecated(self):
Expand Down
16 changes: 8 additions & 8 deletions Lib/test/test_pathlib/test_pathlib_abc.py
Original file line number Diff line number Diff line change
Expand Up @@ -680,6 +680,9 @@ def test_with_name_common(self):
self.assertEqual(P('/a/b.py').with_name('d.xml'), P('/a/d.xml'))
self.assertEqual(P('a/Dot ending.').with_name('d.xml'), P('a/d.xml'))
self.assertEqual(P('/a/Dot ending.').with_name('d.xml'), P('/a/d.xml'))
self.assertRaises(ValueError, P('').with_name, 'd.xml')
self.assertRaises(ValueError, P('/').with_name, 'd.xml')
self.assertRaises(ValueError, P('a/b').with_name, '')

@needs_windows
def test_with_name_windows(self):
Expand All @@ -700,10 +703,7 @@ def test_with_name_windows(self):

def test_with_name_empty(self):
P = self.cls
self.assertEqual(P('').with_name('d.xml'), P('d.xml'))
self.assertEqual(P('.').with_name('d.xml'), P('d.xml'))
self.assertEqual(P('/').with_name('d.xml'), P('/d.xml'))
self.assertEqual(P('a/b').with_name(''), P('a/'))
self.assertEqual(P('a/b').with_name('.'), P('a/.'))

def test_with_name_seps(self):
Expand All @@ -721,6 +721,11 @@ def test_with_stem_common(self):
self.assertEqual(P('/a/b.tar.gz').with_stem('d'), P('/a/d.gz'))
self.assertEqual(P('a/Dot ending.').with_stem('d'), P('a/d.'))
self.assertEqual(P('/a/Dot ending.').with_stem('d'), P('/a/d.'))
self.assertRaises(ValueError, P('').with_stem, 'd')
self.assertRaises(ValueError, P('/').with_stem, 'd')
self.assertRaises(ValueError, P('a/b').with_stem, '')
self.assertRaises(ValueError, P('foo.gz').with_stem, '')
self.assertRaises(ValueError, P('/a/b/foo.gz').with_stem, '')

@needs_windows
def test_with_stem_windows(self):
Expand All @@ -741,13 +746,8 @@ def test_with_stem_windows(self):

def test_with_stem_empty(self):
P = self.cls
self.assertEqual(P('').with_stem('d'), P('d'))
self.assertEqual(P('.').with_stem('d'), P('d'))
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
Expand Down

0 comments on commit 1130cc5

Please sign in to comment.