[3.11] gh-102950: Implement PEP 706 – Filter for tarfile.extractall (GH-102953) (GH-103832)

See [Backporting & Forward Compatibility in PEP 706](https://peps.python.org/pep-0706/#backporting-forward-compatibility).

- Backport b52ad18a76
- Backport c8c3956d90
- Remove the DeprecationWarning
- Adjust docs
- Remove new `__all__` entries
This commit is contained in:
Petr Viktorin 2023-04-28 17:41:09 +02:00 committed by GitHub
parent b3faf8ceec
commit 241f2e54a6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 1800 additions and 97 deletions

View file

@ -1231,7 +1231,7 @@ def _unpack_zipfile(filename, extract_dir):
finally:
zip.close()
def _unpack_tarfile(filename, extract_dir):
def _unpack_tarfile(filename, extract_dir, *, filter=None):
"""Unpack tar/tar.gz/tar.bz2/tar.xz `filename` to `extract_dir`
"""
import tarfile # late import for breaking circular dependency
@ -1241,7 +1241,7 @@ def _unpack_tarfile(filename, extract_dir):
raise ReadError(
"%s is not a compressed or uncompressed tar file" % filename)
try:
tarobj.extractall(extract_dir)
tarobj.extractall(extract_dir, filter=filter)
finally:
tarobj.close()
@ -1274,7 +1274,7 @@ def _find_unpack_format(filename):
return name
return None
def unpack_archive(filename, extract_dir=None, format=None):
def unpack_archive(filename, extract_dir=None, format=None, *, filter=None):
"""Unpack an archive.
`filename` is the name of the archive.
@ -1288,6 +1288,9 @@ def unpack_archive(filename, extract_dir=None, format=None):
was registered for that extension.
In case none is found, a ValueError is raised.
If `filter` is given, it is passed to the underlying
extraction function.
"""
sys.audit("shutil.unpack_archive", filename, extract_dir, format)
@ -1297,6 +1300,10 @@ def unpack_archive(filename, extract_dir=None, format=None):
extract_dir = os.fspath(extract_dir)
filename = os.fspath(filename)
if filter is None:
filter_kwargs = {}
else:
filter_kwargs = {'filter': filter}
if format is not None:
try:
format_info = _UNPACK_FORMATS[format]
@ -1304,7 +1311,7 @@ def unpack_archive(filename, extract_dir=None, format=None):
raise ValueError("Unknown unpack format '{0}'".format(format)) from None
func = format_info[1]
func(filename, extract_dir, **dict(format_info[2]))
func(filename, extract_dir, **dict(format_info[2]), **filter_kwargs)
else:
# we need to look at the registered unpackers supported extensions
format = _find_unpack_format(filename)
@ -1312,7 +1319,7 @@ def unpack_archive(filename, extract_dir=None, format=None):
raise ReadError("Unknown archive format '{0}'".format(filename))
func = _UNPACK_FORMATS[format][1]
kwargs = dict(_UNPACK_FORMATS[format][2])
kwargs = dict(_UNPACK_FORMATS[format][2]) | filter_kwargs
func(filename, extract_dir, **kwargs)