Skip to content

Commit

Permalink
ignore NotADirectoryError on missing_ok = True
Browse files Browse the repository at this point in the history
Semantically equivalent to FileNotFoundError - the file to be unlinked does not exist
  • Loading branch information
MusicalNinjaDad committed Jul 4, 2024
1 parent 6286d80 commit 613cdb2
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 3 deletions.
9 changes: 7 additions & 2 deletions Doc/library/pathlib.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1627,10 +1627,15 @@ example because the path doesn't exist).
If *missing_ok* is false (the default), this method propagates any
:exc:`OSError` from the operating system, including :exc:`FileNotFoundError`.

If *missing_ok* is true, :exc:`FileNotFoundError` exceptions will be
ignored (same behavior as the POSIX ``rm -f`` command), any other
If *missing_ok* is true, this shows similar behavior to the POSIX ``rm -f``
command and any :exc:`FileNotFoundError` or :exc:`NotADirectoryError`
exceptions will be ignored. This means that the file does not exist after
execution, but cannot guarantee that the file did exist before. Any other
:exc:`OSError` which is encountered will continue to be propogated.

.. versionchanged:: 3.??
The *missing_ok* parameter will also ignore :exc:`NotADirectoryError`

.. versionchanged:: 3.8
The *missing_ok* parameter was added.

Expand Down
2 changes: 1 addition & 1 deletion Lib/pathlib/_local.py
Original file line number Diff line number Diff line change
Expand Up @@ -793,7 +793,7 @@ def unlink(self, missing_ok=False):
"""
try:
os.unlink(self)
except FileNotFoundError:
except (FileNotFoundError, NotADirectoryError):
if not missing_ok:
raise

Expand Down
7 changes: 7 additions & 0 deletions Lib/test/test_pathlib/test_pathlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -775,6 +775,13 @@ def test_unlink_missing_ok(self):
self.assertFileNotFound(p.unlink)
p.unlink(missing_ok=True)

def test_unlink_missing_ok_intermediate_file(self):
p = self.cls(self.base) / 'fileAAA'
p.touch()
p = p / 'fileBBB'
self.assertNotADirectory(p.unlink)
p.unlink(missing_ok=True)

def test_rmdir(self):
p = self.cls(self.base) / 'dirA'
for q in p.iterdir():
Expand Down
5 changes: 5 additions & 0 deletions Lib/test/test_pathlib/test_pathlib_abc.py
Original file line number Diff line number Diff line change
Expand Up @@ -1591,6 +1591,11 @@ def assertFileNotFound(self, func, *args, **kwargs):
func(*args, **kwargs)
self.assertEqual(cm.exception.errno, errno.ENOENT)

def assertNotADirectory(self, func, *args, **kwargs):
with self.assertRaises(NotADirectoryError) as cm:
func(*args, **kwargs)
self.assertEqual(cm.exception.errno, errno.ENOTDIR)

def assertEqualNormCase(self, path_a, path_b):
normcase = self.parser.normcase
self.assertEqual(normcase(path_a), normcase(path_b))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
:meth:`pathlib.Path.unlink` will also ignore any :exc:`NotADirectoryError`
if *missing_ok* is true.

0 comments on commit 613cdb2

Please sign in to comment.