mirror of
https://github.com/python/cpython
synced 2024-09-18 21:51:40 +00:00
gh-102828: emit deprecation warning for onerror arg to shutil.rmtree (#102850)
This commit is contained in:
parent
868490e327
commit
7f760c2fca
|
@ -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
|
||||
----------------------------------
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
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):
|
||||
|
|
|
@ -864,8 +864,8 @@ def __init__(self, suffix=None, prefix=None, dir=None,
|
|||
|
||||
@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 @@ def resetperms(path):
|
|||
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):
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
unregister_unpack_format, get_unpack_formats,
|
||||
SameFileError, _GiveupOnFastCopy)
|
||||
import tarfile
|
||||
import warnings
|
||||
import zipfile
|
||||
try:
|
||||
import posix
|
||||
|
@ -207,7 +208,8 @@ def test_rmtree_fails_on_symlink_onerror(self):
|
|||
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 @@ def test_rmtree_fails_on_junctions_onerror(self):
|
|||
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 @@ def test_rmtree_errors_onerror(self):
|
|||
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 @@ def test_on_error(self):
|
|||
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 @@ def onexc(*args):
|
|||
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)
|
||||
|
||||
|
|
Loading…
Reference in a new issue