diff options
author | Irit Katriel <1055913+iritkatriel@users.noreply.github.com> | 2023-03-21 11:08:46 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-21 11:08:46 (GMT) |
commit | 7f760c2fca3dc5f46a518f5b7622783039bc8b7b (patch) | |
tree | 9569716a28604e4d9e6c00a7107d4d8168b6fa61 | |
parent | 868490e32790eb1f1b44bbae2f12d480a23dbdac (diff) | |
download | cpython-7f760c2fca3dc5f46a518f5b7622783039bc8b7b.zip cpython-7f760c2fca3dc5f46a518f5b7622783039bc8b7b.tar.gz cpython-7f760c2fca3dc5f46a518f5b7622783039bc8b7b.tar.bz2 |
gh-102828: emit deprecation warning for onerror arg to shutil.rmtree (#102850)
-rw-r--r-- | Doc/whatsnew/3.12.rst | 10 | ||||
-rw-r--r-- | Lib/shutil.py | 6 | ||||
-rw-r--r-- | Lib/tempfile.py | 8 | ||||
-rw-r--r-- | Lib/test/test_shutil.py | 16 |
4 files changed, 28 insertions, 12 deletions
diff --git a/Doc/whatsnew/3.12.rst b/Doc/whatsnew/3.12.rst index af52c7c..b7c956d 100644 --- a/Doc/whatsnew/3.12.rst +++ b/Doc/whatsnew/3.12.rst @@ -339,7 +339,8 @@ shutil * :func:`shutil.rmtree` now accepts a new argument *onexc* which is an error handler like *onerror* but which expects an exception instance - rather than a *(typ, val, tb)* triplet. *onerror* is deprecated. + rather than a *(typ, val, tb)* triplet. *onerror* is deprecated and + will be removed in Python 3.14. (Contributed by Irit Katriel in :gh:`102828`.) @@ -503,8 +504,8 @@ Deprecated fields are deprecated. Use :data:`sys.last_exc` instead. (Contributed by Irit Katriel in :gh:`102778`.) -* The *onerror* argument of :func:`shutil.rmtree` is deprecated. Use *onexc* - instead. (Contributed by Irit Katriel in :gh:`102828`.) +* The *onerror* argument of :func:`shutil.rmtree` is deprecated as will be removed + in Python 3.14. Use *onexc* instead. (Contributed by Irit Katriel in :gh:`102828`.) Pending Removal in Python 3.13 @@ -586,6 +587,9 @@ Pending Removal in Python 3.14 functions that have been deprecated since Python 2 but only gained a proper :exc:`DeprecationWarning` in 3.12. Remove them in 3.14. +* The *onerror* argument of :func:`shutil.rmtree` is deprecated in 3.12, + and will be removed in 3.14. + Pending Removal in Future Versions ---------------------------------- diff --git a/Lib/shutil.py b/Lib/shutil.py index 89a7ac7..b057640 100644 --- a/Lib/shutil.py +++ b/Lib/shutil.py @@ -10,6 +10,7 @@ import stat import fnmatch import collections import errno +import warnings try: import zlib @@ -692,6 +693,11 @@ def rmtree(path, ignore_errors=False, onerror=None, *, onexc=None, dir_fd=None): onerror is deprecated and only remains for backwards compatibility. If both onerror and onexc are set, onerror is ignored and onexc is used. """ + + if onerror is not None: + warnings.warn("onerror argument is deprecated, use onexc instead", + DeprecationWarning) + sys.audit("shutil.rmtree", path, dir_fd) if ignore_errors: def onexc(*args): diff --git a/Lib/tempfile.py b/Lib/tempfile.py index bb18d60..cf06092 100644 --- a/Lib/tempfile.py +++ b/Lib/tempfile.py @@ -864,8 +864,8 @@ class TemporaryDirectory: @classmethod def _rmtree(cls, name, ignore_errors=False): - def onerror(func, path, exc_info): - if issubclass(exc_info[0], PermissionError): + def onexc(func, path, exc): + if isinstance(exc, PermissionError): def resetperms(path): try: _os.chflags(path, 0) @@ -885,13 +885,13 @@ class TemporaryDirectory: cls._rmtree(path, ignore_errors=ignore_errors) except FileNotFoundError: pass - elif issubclass(exc_info[0], FileNotFoundError): + elif isinstance(exc, FileNotFoundError): pass else: if not ignore_errors: raise - _shutil.rmtree(name, onerror=onerror) + _shutil.rmtree(name, onexc=onexc) @classmethod def _cleanup(cls, name, warn_message, ignore_errors=False): diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py index 89d65af..1c0589c 100644 --- a/Lib/test/test_shutil.py +++ b/Lib/test/test_shutil.py @@ -23,6 +23,7 @@ from shutil import (make_archive, unregister_unpack_format, get_unpack_formats, SameFileError, _GiveupOnFastCopy) import tarfile +import warnings import zipfile try: import posix @@ -207,7 +208,8 @@ class TestRmTree(BaseTest, unittest.TestCase): errors = [] def onerror(*args): errors.append(args) - shutil.rmtree(link, onerror=onerror) + with self.assertWarns(DeprecationWarning): + shutil.rmtree(link, onerror=onerror) self.assertEqual(len(errors), 1) self.assertIs(errors[0][0], os.path.islink) self.assertEqual(errors[0][1], link) @@ -268,7 +270,8 @@ class TestRmTree(BaseTest, unittest.TestCase): errors = [] def onerror(*args): errors.append(args) - shutil.rmtree(link, onerror=onerror) + with self.assertWarns(DeprecationWarning): + shutil.rmtree(link, onerror=onerror) self.assertEqual(len(errors), 1) self.assertIs(errors[0][0], os.path.islink) self.assertEqual(errors[0][1], link) @@ -337,7 +340,8 @@ class TestRmTree(BaseTest, unittest.TestCase): errors = [] def onerror(*args): errors.append(args) - shutil.rmtree(filename, onerror=onerror) + with self.assertWarns(DeprecationWarning): + shutil.rmtree(filename, onerror=onerror) self.assertEqual(len(errors), 2) self.assertIs(errors[0][0], os.scandir) self.assertEqual(errors[0][1], filename) @@ -406,7 +410,8 @@ class TestRmTree(BaseTest, unittest.TestCase): self.addCleanup(os.chmod, self.child_file_path, old_child_file_mode) self.addCleanup(os.chmod, self.child_dir_path, old_child_dir_mode) - shutil.rmtree(TESTFN, onerror=self.check_args_to_onerror) + with self.assertWarns(DeprecationWarning): + shutil.rmtree(TESTFN, onerror=self.check_args_to_onerror) # Test whether onerror has actually been called. self.assertEqual(self.errorState, 3, "Expected call to onerror function did not happen.") @@ -532,7 +537,8 @@ class TestRmTree(BaseTest, unittest.TestCase): self.addCleanup(os.chmod, self.child_file_path, old_child_file_mode) self.addCleanup(os.chmod, self.child_dir_path, old_child_dir_mode) - shutil.rmtree(TESTFN, onerror=onerror, onexc=onexc) + with self.assertWarns(DeprecationWarning): + shutil.rmtree(TESTFN, onerror=onerror, onexc=onexc) self.assertTrue(onexc_called) self.assertFalse(onerror_called) |