(
    filepath: types.PathLike, *, extract_dir: Optional[types.PathLike] = None
)
Extract data from a zip or tar archive file into a directory
    (or do nothing if the file isn't an archive).

    Args:
        filepath: Full path to file on disk from which archived contents will be extracted.
        extract_dir: Full path of the directory into which contents will be extracted.
            If not provided, the same directory as ``filepath`` is used.

    Returns:
        Path to directory of extracted contents.
Extract data from a zip or tar archive file into a directory
    (or do nothing if the file isn't an archive).
Extract data from a zip or tar archive file into a directory ( or do nothing if the file isn t an archive ) .
def unpack_archive(
    filepath: types.PathLike, *, extract_dir: Optional[types.PathLike] = None
) -> types.PathLike:
    """
    Extract data from a zip or tar archive file into a directory
    (or do nothing if the file isn't an archive).

    Args:
        filepath: Full path to file on disk from which archived contents will be extracted.
        extract_dir: Full path of the directory into which contents will be extracted.
            If not provided, the same directory as ``filepath`` is used.

    Returns:
        Path to directory of extracted contents.
    """
    filepath = utils.to_path(filepath).resolve()
    if not extract_dir:
        extract_dir = str(filepath.parent)
    filepath = str(filepath)
    os.makedirs(extract_dir, exist_ok=True)
    is_zipfile = zipfile.is_zipfile(filepath)
    is_tarfile = tarfile.is_tarfile(filepath)
    if not is_zipfile and not is_tarfile:
        LOGGER.debug("'%s' is not an archive", filepath)
        return extract_dir
    else:
        LOGGER.info("extracting data from archive file '%s'", filepath)
        shutil.unpack_archive(filepath, extract_dir=extract_dir, format=None)
        # we want to rename the unpacked directory to a consistent value
        # unfortunately, shutil doesn't pass this back to us
        # so, we get the root path of all the constituent members
        if is_zipfile:
            with zipfile.ZipFile(filepath, mode="r") as zf:
                members = zf.namelist()
        else:
            with tarfile.open(filepath, mode="r") as tf:
                members = tf.getnames()
        src_basename = os.path.commonpath(members)
        dest_basename = os.path.basename(filepath)
        if src_basename:
            while True:
                tmp, _ = os.path.splitext(dest_basename)
                if tmp == dest_basename:
                    break
                else:
                    dest_basename = tmp
            if src_basename != dest_basename:
                return shutil.move(
                    os.path.join(extract_dir, src_basename),
                    os.path.join(extract_dir, dest_basename),
                )
            else:
                return os.path.join(extract_dir, src_basename)
        else:
            return extract_dir
def unpack_archive ( filepath : types . PathLike , * , extract_dir : Optional [ types . PathLike ] = None ) -> types . PathLike : filepath = utils . to_path ( filepath ) . resolve ( ) if not extract_dir : extract_dir = str ( filepath . parent ) filepath = str ( filepath ) os . makedirs ( extract_dir , exist_ok = True ) is_zipfile = zipfile . is_zipfile ( filepath ) is_tarfile = tarfile . is_tarfile ( filepath ) if not is_zipfile and not is_tarfile : LOGGER . debug ( "'%s' is not an archive" , filepath ) return extract_dir else : LOGGER . info ( "extracting data from archive file '%s'" , filepath ) shutil . unpack_archive ( filepath , extract_dir = extract_dir , format = None ) # we want to rename the unpacked directory to a consistent value # unfortunately, shutil doesn't pass this back to us # so, we get the root path of all the constituent members if is_zipfile : with zipfile . ZipFile ( filepath , mode = "r" ) as zf : members = zf . namelist ( ) else : with tarfile . open ( filepath , mode = "r" ) as tf : members = tf . getnames ( ) src_basename = os . path . commonpath ( members ) dest_basename = os . path . basename ( filepath ) if src_basename : while True : tmp , _ = os . path . splitext ( dest_basename ) if tmp == dest_basename : break else : dest_basename = tmp if src_basename != dest_basename : return shutil . move ( os . path . join ( extract_dir , src_basename ) , os . path . join ( extract_dir , dest_basename ) , ) else : return os . path . join ( extract_dir , src_basename ) else : return extract_dir