# Buggy code
def extract_archive(path, to_directory=".", merge_single=True, extractor=None):
    path = os.path.abspath(path)
    mode = None
    logger.debug("Extracting %s to %s", path, to_directory)

    if extractor is None:
        if path.endswith(".tar.gz") or path.endswith(".tgz"):
            extractor = "tgz"
        elif path.endswith(".tar.xz") or path.endswith(".txz"):
            extractor = "txz"
        elif path.endswith(".tar"):
            extractor = "tar"
        elif path.endswith(".tar.bz2") or path.endswith(".tbz"):
            extractor = "bz2"
        elif path.endswith(".gz"):
            extractor = "gzip"
        elif path.endswith(".exe"):
            extractor = "exe"
        elif is_7zip_supported(path, None):
            extractor = None
        else:
            raise RuntimeError(
                "Could not extract `%s` - no appropriate extractor found" % path
            )

    if extractor == "tgz":
        opener, mode = tarfile.open, "r:gz"
    elif extractor == "txz":
        opener, mode = tarfile.open, "r:xz"
    elif extractor == "tar":
        opener, mode = tarfile.open, "r:"
    elif extractor == "bz2":
        opener, mode = tarfile.open, "r:bz2"
    elif extractor == "gzip":
        decompress_gz(path, to_directory)
        return
    elif extractor == "gog":
        opener = "innoextract"
    elif extractor == "exe":
        opener = "exe"
    elif extractor is None or is_7zip_supported(path, extractor):
        opener = "7zip"
    else:
        raise RuntimeError("Could not extract `%s` - unknown format specified" % path)

    temp_name = ".extract-" + str(uuid.uuid4())[:8]
    temp_path = temp_dir = os.path.join(to_directory, temp_name)
    try:
        _do_extract(path, temp_path, opener, mode, extractor)
    except (OSError, zlib.error, tarfile.ReadError, EOFError) as ex:
        logger.exception("Extraction failed: %s", ex)
        raise ExtractFailure(str(ex))
    if merge_single:
        extracted = os.listdir(temp_path)
        if len(extracted) == 1:
            temp_path = os.path.join(temp_path, extracted[0])

    if os.path.isfile(temp_path):
        destination_path = os.path.join(to_directory, extracted[0])
        if os.path.isfile(destination_path):
            logger.warning("Overwrite existing file %s", destination_path)
            os.remove(destination_path)
        shutil.move(temp_path, to_directory)
        os.removedirs(temp_dir)
    else:
        for archive_file in os.listdir(temp_path):
            source_path = os.path.join(temp_path, archive_file)
            destination_path = os.path.join(to_directory, archive_file)
            # logger.debug("Moving extracted files from %s to %s", source_path, destination_path)

            if system.path_exists(destination_path):
                logger.warning("Overwrite existing path %s", destination_path)
                if os.path.isfile(destination_path):
                    os.remove(destination_path)
                    shutil.move(source_path, destination_path)
                elif os.path.isdir(destination_path):
                    try:
                        system.merge_folders(source_path, destination_path)
                    except OSError as ex:
                        logger.error(
                            "Failed to merge to destination %s: %s",
                            destination_path,
                            ex,
                        )
                        raise ExtractFailure(str(ex))
            else:
                shutil.move(source_path, destination_path)
        system.remove_folder(temp_dir)
    logger.debug("Finished extracting %s to %s", path, to_directory)
    return path, to_directory


# Traceback (tarfile.ReadError)
DEBUG    2019-11-26 02:20:55,510 [application.launch:339]:Launching Overwatch (wine) (139814221039744)
DEBUG    2019-11-26 02:20:55,543 [game.play:295]:Prelaunching <lutris.runners.wine.wine object at 0x7f290bc16c10>
DEBUG    2019-11-26 02:20:55,765 [downloader.start:55]:Starting download of:
https://github.com/doitsujin/dxvk/releases/download/vdxvk-time2/dxvk-dxvk-time2.tar.gz
DEBUG    2019-11-26 02:20:56,518 [downloader.on_done:97]:Finished downloading https://github.com/doitsujin/dxvk/releases/download/vdxvk-time2/dxvk-dxvk-time2.tar.gz
DEBUG    2019-11-26 02:20:56,668 [extract.extract_archive:69]:Extracting /home/alex/.local/share/lutris/runtime/dxvk/dxvk-dxvk-time2.tar.gz to /home/alex/.local/share/lutris/runtime/dxvk/dxvk-time2
ERROR    2019-11-26 02:20:56,668 [extract.extract_archive:116]:Extraction failed: not a gzip file
Traceback (most recent call last):
File "/usr/lib/python3.8/tarfile.py", line 1671, in gzopen
t = cls.taropen(name, mode, fileobj, **kwargs)
File "/usr/lib/python3.8/tarfile.py", line 1647, in taropen
return cls(name, mode, fileobj, **kwargs)
File "/usr/lib/python3.8/tarfile.py", line 1510, in __init__
self.firstmember = self.next()
File "/usr/lib/python3.8/tarfile.py", line 2313, in next
tarinfo = self.tarinfo.fromtarfile(self)
File "/usr/lib/python3.8/tarfile.py", line 1102, in fromtarfile
buf = tarfile.fileobj.read(BLOCKSIZE)
File "/usr/lib/python3.8/gzip.py", line 286, in read
return self._buffer.read(size)
File "/usr/lib/python3.8/_compression.py", line 68, in readinto
data = self.read(len(byte_view))
File "/usr/lib/python3.8/gzip.py", line 473, in read
if not self._read_gzip_header():
File "/usr/lib/python3.8/gzip.py", line 421, in _read_gzip_header
raise BadGzipFile('Not a gzipped file (%r)' % magic)
gzip.BadGzipFile: Not a gzipped file (b'No')

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/usr/lib/python3.8/site-packages/lutris/util/extract.py", line 114, in extract_archive
_do_extract(path, temp_path, opener, mode, extractor)
File "/usr/lib/python3.8/site-packages/lutris/util/extract.py", line 166, in _do_extract
handler = opener(archive, mode)
File "/usr/lib/python3.8/tarfile.py", line 1617, in open
return func(name, filemode, fileobj, **kwargs)
File "/usr/lib/python3.8/tarfile.py", line 1675, in gzopen
raise ReadError("not a gzip file")
tarfile.ReadError: not a gzip file
ERROR    2019-11-26 02:20:56,669 [jobs.target:32]:Error while completing task <bound method wine.prelaunch of <lutris.runners.wine.wine object at 0x7f290bc16c10>>: not a gzip file
<class 'lutris.util.extract.ExtractFailure'> not a gzip file
File "/usr/lib/python3.8/site-packages/lutris/util/jobs.py", line 30, in target
result = self.function(*args, **kwargs)
File "/usr/lib/python3.8/site-packages/lutris/runners/wine.py", line 794, in prelaunch
self.setup_dxvk(
File "/usr/lib/python3.8/site-packages/lutris/runners/wine.py", line 775, in setup_dxvk
self.toggle_dxvk(
File "/usr/lib/python3.8/site-packages/lutris/runners/wine.py", line 760, in toggle_dxvk
dxvk_manager.download()
File "/usr/lib/python3.8/site-packages/lutris/util/wine/dxvk.py", line 142, in download
extract_archive(dxvk_archive_path, self.dxvk_path, merge_single=True)
File "/usr/lib/python3.8/site-packages/lutris/util/extract.py", line 117, in extract_archive
raise ExtractFailure(str(ex))
ERROR    2019-11-26 02:20:56,669 [game.configure_game:312]:not a gzip file
ERROR    2019-11-26 02:20:58,157 [game.configure_game:315]:Game prelaunch unsuccessful
TypeError: refresh() takes 1 positional argument but 3 were given

# Fixed code
def extract_archive(path, to_directory=".", merge_single=True, extractor=None):
    path = os.path.abspath(path)
    mode = None
    logger.debug("Extracting %s to %s", path, to_directory)

    if extractor is None:
        if path.endswith(".tar.gz") or path.endswith(".tgz"):
            extractor = "tgz"
        elif path.endswith(".tar.xz") or path.endswith(".txz"):
            extractor = "txz"
        elif path.endswith(".tar"):
            extractor = "tar"
        elif path.endswith(".tar.bz2") or path.endswith(".tbz"):
            extractor = "bz2"
        elif path.endswith(".gz"):
            extractor = "gzip"
        elif path.endswith(".exe"):
            extractor = "exe"
        elif is_7zip_supported(path, None):
            extractor = None
        else:
            raise RuntimeError(
                "Could not extract `%s` - no appropriate extractor found" % path
            )

    if extractor == "tgz":
        opener, mode = tarfile.open, "r:gz"
    elif extractor == "txz":
        opener, mode = tarfile.open, "r:xz"
    elif extractor == "tar":
        opener, mode = tarfile.open, "r:"
    elif extractor == "bz2":
        opener, mode = tarfile.open, "r:bz2"
    elif extractor == "gzip":
        decompress_gz(path, to_directory)
        return
    elif extractor == "gog":
        opener = "innoextract"
    elif extractor == "exe":
        opener = "exe"
    elif extractor is None or is_7zip_supported(path, extractor):
        opener = "7zip"
    else:
        raise RuntimeError("Could not extract `%s` - unknown format specified" % path)

    temp_name = ".extract-" + str(uuid.uuid4())[:8]
    temp_path = temp_dir = os.path.join(to_directory, temp_name)
    try:
        _do_extract(path, temp_path, opener, mode, extractor)
    except (OSError, zlib.error, tarfile.ReadError, EOFError) as ex:
        logger.error("Extraction failed: %s", ex)
        raise ExtractFailure(str(ex))
    if merge_single:
        extracted = os.listdir(temp_path)
        if len(extracted) == 1:
            temp_path = os.path.join(temp_path, extracted[0])

    if os.path.isfile(temp_path):
        destination_path = os.path.join(to_directory, extracted[0])
        if os.path.isfile(destination_path):
            logger.warning("Overwrite existing file %s", destination_path)
            os.remove(destination_path)
        shutil.move(temp_path, to_directory)
        os.removedirs(temp_dir)
    else:
        for archive_file in os.listdir(temp_path):
            source_path = os.path.join(temp_path, archive_file)
            destination_path = os.path.join(to_directory, archive_file)
            # logger.debug("Moving extracted files from %s to %s", source_path, destination_path)

            if system.path_exists(destination_path):
                logger.warning("Overwrite existing path %s", destination_path)
                if os.path.isfile(destination_path):
                    os.remove(destination_path)
                    shutil.move(source_path, destination_path)
                elif os.path.isdir(destination_path):
                    try:
                        system.merge_folders(source_path, destination_path)
                    except OSError as ex:
                        logger.error(
                            "Failed to merge to destination %s: %s",
                            destination_path,
                            ex,
                        )
                        raise ExtractFailure(str(ex))
            else:
                shutil.move(source_path, destination_path)
        system.remove_folder(temp_dir)
    logger.debug("Finished extracting %s to %s", path, to_directory)
    return path, to_directory