# Path: monty/io.py
# def zopen(filename: Union[str, Path], *args, **kwargs) -> IO:
#     r"""
#     This function wraps around the bz2, gzip, lzma, xz and standard python's open
#     function to deal intelligently with bzipped, gzipped or standard text
#     files.
# 
#     Args:
#         filename (str/Path): filename or pathlib.Path.
#         *args: Standard args for python open(..). E.g., 'r' for read, 'w' for
#             write.
#         **kwargs: Standard kwargs for python open(..).
# 
#     Returns:
#         File-like object. Supports with context.
#     """
#     if Path is not None and isinstance(filename, Path):
#         filename = str(filename)
# 
#     name, ext = os.path.splitext(filename)
#     ext = ext.upper()
#     if ext == ".BZ2":
#         return bz2.open(filename, *args, **kwargs)
#     if ext in (".GZ", ".Z"):
#         return gzip.open(filename, *args, **kwargs)
#     if ext in (".XZ", ".LZMA"):
#         return lzma.open(filename, *args, **kwargs)
#     return open(filename, *args, **kwargs)  # pylint: disable=R1732


import os
import shutil
import warnings
from gzip import GzipFile
from .io import zopen

def compress_dir(path, compression="gz"):
    """
    Recursively compresses all files in a directory. Note that this
    compresses all files singly, i.e., it does not create a tar archive. For
    that, just use Python tarfile class.

    Args:
        path (str): Path to parent directory.
        compression (str): A compression mode. Valid options are "gz" or
            "bz2". Defaults to gz.
    """
    for parent, subdirs, files in os.walk(path):
        for f in files:
            compress_file(os.path.join(parent, f), compression=compression)


def decompress_file(filepath):
    """
    Decompresses a file with the correct extension. Automatically detects
    gz, bz2 or z extension.

    Args:
        filepath (str): Path to file.
        compression (str): A compression mode. Valid options are "gz" or
            "bz2". Defaults to "gz".
    """
    toks = filepath.split(".")
    file_ext = toks[-1].upper()
    if file_ext in ["BZ2", "GZ", "Z"]:

# Path: monty/io.py
# def zopen(filename: Union[str, Path], *args, **kwargs) -> IO:
#     r"""
#     This function wraps around the bz2, gzip, lzma, xz and standard python's open
#     function to deal intelligently with bzipped, gzipped or standard text
#     files.
# 
#     Args:
#         filename (str/Path): filename or pathlib.Path.
#         *args: Standard args for python open(..). E.g., 'r' for read, 'w' for
#             write.
#         **kwargs: Standard kwargs for python open(..).
# 
#     Returns:
#         File-like object. Supports with context.
#     """
#     if Path is not None and isinstance(filename, Path):
#         filename = str(filename)
# 
#     name, ext = os.path.splitext(filename)
#     ext = ext.upper()
#     if ext == ".BZ2":
#         return bz2.open(filename, *args, **kwargs)
#     if ext in (".GZ", ".Z"):
#         return gzip.open(filename, *args, **kwargs)
#     if ext in (".XZ", ".LZMA"):
#         return lzma.open(filename, *args, **kwargs)
#     return open(filename, *args, **kwargs)  # pylint: disable=R1732


# Path: monty/shutil.py
import os
import shutil
import warnings
from gzip import GzipFile
from .io import zopen


def compress_dir(path, compression="gz"):
    """
    Recursively compresses all files in a directory. Note that this
    compresses all files singly, i.e., it does not create a tar archive. For
    that, just use Python tarfile class.

    Args:
        path (str): Path to parent directory.
        compression (str): A compression mode. Valid options are "gz" or
            "bz2". Defaults to gz.
    """
    for parent, subdirs, files in os.walk(path):
        for f in files:
            compress_file(os.path.join(parent, f), compression=compression)


def decompress_file(filepath):
    """
    Decompresses a file with the correct extension. Automatically detects
    gz, bz2 or z extension.

    Args:
        filepath (str): Path to file.
        compression (str): A compression mode. Valid options are "gz" or
            "bz2". Defaults to "gz".
    """
    toks = filepath.split(".")
    file_ext = toks[-1].upper()
    if file_ext in ["BZ2", "GZ", "Z"]:

        with open(".".join(toks[0:-1]), "wb") as f_out, zopen(filepath, "rb") as f_in: