# Buggy code
def is_unarchived(self):
    cmd = [self.cmd_path, "--diff", "-C", self.dest]
    if self.zipflag:
        cmd.append(self.zipflag)
    if self.opts:
        cmd.extend(["--show-transformed-names"] + self.opts)
    if self.file_args["owner"]:
        cmd.append("--owner=" + quote(self.file_args["owner"]))
    if self.file_args["group"]:
        cmd.append("--group=" + quote(self.file_args["group"]))
    if self.module.params["keep_newer"]:
        cmd.append("--keep-newer-files")
    if self.excludes:
        cmd.extend(["--exclude=" + f for f in self.excludes])
    cmd.extend(["-f", self.src])
    rc, out, err = self.module.run_command(
        cmd, cwd=self.dest, environ_update=dict(LANG="C", LC_ALL="C", LC_MESSAGES="C")
    )

    # Check whether the differences are in something that we're
    # setting anyway

    # What is different
    unarchived = True
    old_out = out
    out = ""
    run_uid = os.getuid()
    # When unarchiving as a user, or when owner/group/mode is supplied --diff is insufficient
    # Only way to be sure is to check request with what is on disk (as we do for zip)
    # Leave this up to set_fs_attributes_if_different() instead of inducing a (false) change
    for line in old_out.splitlines() + err.splitlines():
        # FIXME: Remove the bogus lines from error-output as well !
        # Ignore bogus errors on empty filenames (when using --split-component)
        if EMPTY_FILE_RE.search(line):
            continue
        if run_uid == 0 and not self.file_args["owner"] and OWNER_DIFF_RE.search(line):
            out += line + "\n"
        if run_uid == 0 and not self.file_args["group"] and GROUP_DIFF_RE.search(line):
            out += line + "\n"
        if not self.file_args["mode"] and MODE_DIFF_RE.search(line):
            out += line + "\n"
        if MOD_TIME_DIFF_RE.search(line):
            out += line + "\n"
        if MISSING_FILE_RE.search(line):
            out += line + "\n"
        if INVALID_OWNER_RE.search(line):
            out += line + "\n"
        if INVALID_GROUP_RE.search(line):
            out += line + "\n"
    if out:
        unarchived = False
    return dict(unarchived=unarchived, rc=rc, out=out, err=err, cmd=cmd)


# Traceback (nUnicodeEncodeError)
TASK [unarchive : test that unarchive works with an archive that contains non-ascii filenames] **************************************************************************
fatal: [testhost]: FAILED! => {"changed": false, "module_stderr": "Shared connection to localhost closed.\r\n", "module_stdout": "Traceback (most recent call last):\r\n  File \"/root/.ansible/tmp/ansible-tmp-1561576726.3763218-37161750934991/AnsiballZ_unarchive.py\", line 139, in <module>\r\n    _ansiballz_main()\r\n  File \"/root/.ansible/tmp/ansible-tmp-1561576726.3763218-37161750934991/AnsiballZ_unarchive.py\", line 131, in _ansiballz_main\r\n    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\r\n  File \"/root/.ansible/tmp/ansible-tmp-1561576726.3763218-37161750934991/AnsiballZ_unarchive.py\", line 65, in invoke_module\r\n    spec.loader.exec_module(module)\r\n  File \"<frozen importlib._bootstrap_external>\", line 678, in exec_module\r\n  File \"<frozen importlib._bootstrap>\", line 219, in _call_with_frames_removed\r\n  File \"/tmp/ansible_unarchive_payload_o9_x930g/__main__.py\", line 909, in <module>\r\n  File \"/tmp/ansible_unarchive_payload_o9_x930g/__main__.py\", line 859, in main\r\n  File \"/usr/local/lib/python3.6/genericpath.py\", line 42, in isdir\r\n    st = os.stat(s)\r\nUnicodeEncodeError: 'ascii' codec can't encode characters in position 51-54: ordinal not in range(128)\r\n", "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", "rc": 1}

# Fixed code
def is_unarchived(self):
    cmd = [self.cmd_path, "--diff", "-C", self.b_dest]
    if self.zipflag:
        cmd.append(self.zipflag)
    if self.opts:
        cmd.extend(["--show-transformed-names"] + self.opts)
    if self.file_args["owner"]:
        cmd.append("--owner=" + quote(self.file_args["owner"]))
    if self.file_args["group"]:
        cmd.append("--group=" + quote(self.file_args["group"]))
    if self.module.params["keep_newer"]:
        cmd.append("--keep-newer-files")
    if self.excludes:
        cmd.extend(["--exclude=" + f for f in self.excludes])
    cmd.extend(["-f", self.src])
    rc, out, err = self.module.run_command(
        cmd, cwd=self.b_dest, environ_update=dict(LANG="C", LC_ALL="C", LC_MESSAGES="C")
    )

    # Check whether the differences are in something that we're
    # setting anyway

    # What is different
    unarchived = True
    old_out = out
    out = ""
    run_uid = os.getuid()
    # When unarchiving as a user, or when owner/group/mode is supplied --diff is insufficient
    # Only way to be sure is to check request with what is on disk (as we do for zip)
    # Leave this up to set_fs_attributes_if_different() instead of inducing a (false) change
    for line in old_out.splitlines() + err.splitlines():
        # FIXME: Remove the bogus lines from error-output as well !
        # Ignore bogus errors on empty filenames (when using --split-component)
        if EMPTY_FILE_RE.search(line):
            continue
        if run_uid == 0 and not self.file_args["owner"] and OWNER_DIFF_RE.search(line):
            out += line + "\n"
        if run_uid == 0 and not self.file_args["group"] and GROUP_DIFF_RE.search(line):
            out += line + "\n"
        if not self.file_args["mode"] and MODE_DIFF_RE.search(line):
            out += line + "\n"
        if MOD_TIME_DIFF_RE.search(line):
            out += line + "\n"
        if MISSING_FILE_RE.search(line):
            out += line + "\n"
        if INVALID_OWNER_RE.search(line):
            out += line + "\n"
        if INVALID_GROUP_RE.search(line):
            out += line + "\n"
    if out:
        unarchived = False
    return dict(unarchived=unarchived, rc=rc, out=out, err=err, cmd=cmd)