Extract all members from the archive to the current working directory and set owner, modification time and permissions on directories afterwards. 'path' specifies a different directory to extract to. 'members' is optional and must be a subset of the list r
(self, path=".", members=None, *, numeric_owner=False,
filter=None)
| 2405 | raise ValueError(f"filter {filter!r} not found") from None |
| 2406 | |
| 2407 | def extractall(self, path=".", members=None, *, numeric_owner=False, |
| 2408 | filter=None): |
| 2409 | """Extract all members from the archive to the current working |
| 2410 | directory and set owner, modification time and permissions on |
| 2411 | directories afterwards. 'path' specifies a different directory |
| 2412 | to extract to. 'members' is optional and must be a subset of the |
| 2413 | list returned by getmembers(). If 'numeric_owner' is True, only |
| 2414 | the numbers for user/group names are used and not the names. |
| 2415 | |
| 2416 | The 'filter' function will be called on each member just |
| 2417 | before extraction. |
| 2418 | It can return a changed TarInfo or None to skip the member. |
| 2419 | String names of common filters are accepted. |
| 2420 | """ |
| 2421 | directories = [] |
| 2422 | |
| 2423 | filter_function = self._get_filter_function(filter) |
| 2424 | if members is None: |
| 2425 | members = self |
| 2426 | |
| 2427 | for member in members: |
| 2428 | tarinfo, unfiltered = self._get_extract_tarinfo( |
| 2429 | member, filter_function, path) |
| 2430 | if tarinfo is None: |
| 2431 | continue |
| 2432 | if tarinfo.isdir(): |
| 2433 | # For directories, delay setting attributes until later, |
| 2434 | # since permissions can interfere with extraction and |
| 2435 | # extracting contents can reset mtime. |
| 2436 | directories.append(unfiltered) |
| 2437 | self._extract_one(tarinfo, path, set_attrs=not tarinfo.isdir(), |
| 2438 | numeric_owner=numeric_owner, |
| 2439 | filter_function=filter_function) |
| 2440 | |
| 2441 | # Reverse sort directories. |
| 2442 | directories.sort(key=lambda a: a.name, reverse=True) |
| 2443 | |
| 2444 | |
| 2445 | # Set correct owner, mtime and filemode on directories. |
| 2446 | for unfiltered in directories: |
| 2447 | try: |
| 2448 | # Need to re-apply any filter, to take the *current* filesystem |
| 2449 | # state into account. |
| 2450 | try: |
| 2451 | tarinfo = filter_function(unfiltered, path) |
| 2452 | except _FILTER_ERRORS as exc: |
| 2453 | self._log_no_directory_fixup(unfiltered, repr(exc)) |
| 2454 | continue |
| 2455 | if tarinfo is None: |
| 2456 | self._log_no_directory_fixup(unfiltered, |
| 2457 | 'excluded by filter') |
| 2458 | continue |
| 2459 | dirpath = os.path.join(path, tarinfo.name) |
| 2460 | try: |
| 2461 | lstat = os.lstat(dirpath) |
| 2462 | except FileNotFoundError: |
| 2463 | self._log_no_directory_fixup(tarinfo, 'missing') |
| 2464 | continue |