diff --git a/archive_path/tar_path.py b/archive_path/tar_path.py index 3d93b0d..8a1907a 100644 --- a/archive_path/tar_path.py +++ b/archive_path/tar_path.py @@ -9,7 +9,7 @@ from contextlib import contextmanager, suppress import io import itertools -from pathlib import Path +from pathlib import Path, PurePosixPath import posixpath import tarfile from types import TracebackType @@ -399,7 +399,12 @@ def extract_tree( :param cb_descript: the description to return in the callback + :raises NotADirectoryError: If the zip path is not a directory + """ + if not self.is_dir(): + raise NotADirectoryError(f"Source is not a directory: {self.at}") + if callback is None: callback = lambda action, value: None # noqa: E731 else: @@ -407,6 +412,11 @@ def extract_tree( count = sum(1 for _ in self.glob(pattern, include_virtual=False)) callback("init", {"total": count, "description": cb_descript}) + # always make base directory + Path(outpath).joinpath(PurePosixPath(self.at)).mkdir( + parents=True, exist_ok=True + ) + for path in self.glob(pattern, include_virtual=False): callback("update", 1) info = self._tarfile.getmember(path.at) diff --git a/archive_path/zip_path.py b/archive_path/zip_path.py index a155909..a7c445b 100644 --- a/archive_path/zip_path.py +++ b/archive_path/zip_path.py @@ -14,7 +14,7 @@ import io import itertools import os -from pathlib import Path +from pathlib import Path, PurePosixPath import posixpath import threading from types import TracebackType @@ -410,7 +410,12 @@ def extract_tree( :param cb_descript: the description to return in the callback + :raises NotADirectoryError: If the zip path is not a directory + """ + if not self.is_dir(): + raise NotADirectoryError(f"Source is not a directory: {self.at}") + outpath = cast(str, os.path.abspath(outpath)) if callback is None: @@ -420,6 +425,11 @@ def extract_tree( count = sum(1 for _ in self.glob(pattern, include_virtual=False)) callback("init", {"total": count, "description": cb_descript}) + # always make base directory + Path(outpath).joinpath(PurePosixPath(self.at)).mkdir( + parents=True, exist_ok=True + ) + for path in self.glob(pattern, include_virtual=False): callback("update", 1) try: