From d9e006bcefe6fac859b1b5d741725b9a91991044 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=AEzlohhcuB=20treboR?= Date: Thu, 16 May 2019 00:02:11 +0200 Subject: [PATCH] bpo-33123: pathlib: Add missing_ok parameter to Path.unlink (GH-6191) Similarly to how several pathlib file creation functions have an "exists_ok" parameter, we should introduce "missing_ok" that makes removal functions not raise an exception when a file or directory is already absent. IMHO, this should cover Path.unlink and Path.rmdir. Note, Path.resolve() has a "strict" parameter since 3.6 that does the same thing. Naming this of this new parameter tries to be consistent with the "exists_ok" parameter as that is more explicit about what it does (as opposed to "strict"). https://bugs.python.org/issue33123 --- Doc/library/pathlib.rst | 11 ++++++++++- Lib/pathlib.py | 8 ++++++-- Lib/test/test_pathlib.py | 5 +++++ .../Library/2018-03-22-19-13-19.bpo-33123._Y5ooE.rst | 2 ++ 4 files changed, 23 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2018-03-22-19-13-19.bpo-33123._Y5ooE.rst diff --git a/Doc/library/pathlib.rst b/Doc/library/pathlib.rst index 41aebc4f61c..166de8de1f0 100644 --- a/Doc/library/pathlib.rst +++ b/Doc/library/pathlib.rst @@ -1048,11 +1048,20 @@ call fails (for example because the path doesn't exist). otherwise :exc:`FileExistsError` is raised. -.. method:: Path.unlink() +.. method:: Path.unlink(missing_ok=False) Remove this file or symbolic link. If the path points to a directory, use :func:`Path.rmdir` instead. + If *missing_ok* is false (the default), :exc:`FileNotFoundError` is + raised if the path does not exist. + + If *missing_ok* is true, :exc:`FileNotFoundError` exceptions will be + ignored (same behavior as the POSIX ``rm -f`` command). + + .. versionchanged:: 3.8 + The *missing_ok* parameter was added. + .. method:: Path.link_to(target) diff --git a/Lib/pathlib.py b/Lib/pathlib.py index 952cd94921e..b5bab1fe8f5 100644 --- a/Lib/pathlib.py +++ b/Lib/pathlib.py @@ -1279,14 +1279,18 @@ class Path(PurePath): self._raise_closed() self._accessor.lchmod(self, mode) - def unlink(self): + def unlink(self, missing_ok=False): """ Remove this file or link. If the path is a directory, use rmdir() instead. """ if self._closed: self._raise_closed() - self._accessor.unlink(self) + try: + self._accessor.unlink(self) + except FileNotFoundError: + if not missing_ok: + raise def rmdir(self): """ diff --git a/Lib/test/test_pathlib.py b/Lib/test/test_pathlib.py index 990207b9c4e..caad1c23876 100644 --- a/Lib/test/test_pathlib.py +++ b/Lib/test/test_pathlib.py @@ -1635,6 +1635,11 @@ class _BasePathTest(object): self.assertFileNotFound(p.stat) self.assertFileNotFound(p.unlink) + def test_unlink_missing_ok(self): + p = self.cls(BASE) / 'fileAAA' + self.assertFileNotFound(p.unlink) + p.unlink(missing_ok=True) + def test_rmdir(self): p = self.cls(BASE) / 'dirA' for q in p.iterdir(): diff --git a/Misc/NEWS.d/next/Library/2018-03-22-19-13-19.bpo-33123._Y5ooE.rst b/Misc/NEWS.d/next/Library/2018-03-22-19-13-19.bpo-33123._Y5ooE.rst new file mode 100644 index 00000000000..8803ca84313 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-03-22-19-13-19.bpo-33123._Y5ooE.rst @@ -0,0 +1,2 @@ +:class:`pathlib.Path.unlink` now accepts a *missing_ok* parameter to avoid a +:exc:`FileNotFoundError` from being raised. Patch by Robert Buchholz.