# Buggy code
def uncomment(name, regex, char="#", backup=".bak"):
    """
    Uncomment specified commented lines in a file

    name
        The full path to the file to be edited
    regex
        A regular expression used to find the lines that are to be uncommented.
        This regex should not include the comment character. A leading ``^``
        character will be stripped for convenience (for easily switching
        between comment() and uncomment()).  The regex will be searched for
        from the beginning of the line, ignoring leading spaces (we prepend
        '^[ \\t]*')
    char : ``#``
        The character to remove in order to uncomment a line
    backup : ``.bak``
        The file will be backed up before edit with this file extension;
        **WARNING:** each time ``sed``/``comment``/``uncomment`` is called will
        overwrite this backup

    Usage:

    .. code-block:: yaml

        /etc/adduser.conf:
          file.uncomment:
            - regex: EXTRA_GROUPS

    .. versionadded:: 0.9.5
    """
    ret = {"name": name, "changes": {}, "result": False, "comment": ""}

    check_res, check_msg = _check_file(name)
    if not check_res:
        return _error(ret, check_msg)

    # Make sure the pattern appears in the file
    if __salt__["file.contains_regex_multiline"](
        name, "^[ \t]*{0}".format(regex.lstrip("^"))
    ):
        ret["comment"] = "Pattern already uncommented"
        ret["result"] = True
        return ret
    elif __salt__["file.contains_regex_multiline"](
        name, "{0}[ \t]*{1}".format(char, regex.lstrip("^"))
    ):
        # Line exists and is commented
        pass
    else:
        return _error(ret, "{0}: Pattern not found".format(regex))

    if __opts__["test"]:
        ret["comment"] = "File {0} is set to be updated".format(name)
        ret["result"] = None
        return ret

    with salt.utils.fopen(name, "rb") as fp_:
        slines = fp_.readlines()

    # Perform the edit
    __salt__["file.uncomment"](name, regex, char, backup)

    with salt.utils.fopen(name, "rb") as fp_:
        nlines = fp_.readlines()

    # Check the result
    ret["result"] = __salt__["file.contains_regex_multiline"](
        name, "^[ \t]*{0}".format(regex.lstrip("^"))
    )

    if slines != nlines:
        if not salt.utils.istextfile(name):
            ret["changes"]["diff"] = "Replace binary file"
        else:
            # Changes happened, add them
            ret["changes"]["diff"] = "".join(difflib.unified_diff(slines, nlines))

    if ret["result"]:
        ret["comment"] = "Uncommented lines successfully"
    else:
        ret["comment"] = "Expected uncommented lines not found"

    return ret


# Traceback (TypeError)
2014-11-24 16:03:42,245 [salt.minion      ][WARNING ] TypeError encountered executing state.highstate: expected string or buffer. See debug log for more info.  Possibly a missing arguments issue:  ArgSpec(args=['test', 'queue'], varargs=None, keywords='kwargs', defaults=(None, False))
Traceback (most recent call last):
File "/usr/lib/pymodules/python2.7/salt/minion.py", line 809, in _thread_return
return_data = func(*args, **kwargs)
File "/usr/lib/pymodules/python2.7/salt/modules/state.py", line 275, in highstate
force=kwargs.get('force', False)
File "/usr/lib/pymodules/python2.7/salt/state.py", line 2546, in call_highstate
return self.state.call_high(high)
File "/usr/lib/pymodules/python2.7/salt/state.py", line 1715, in call_high
ret = self.call_chunks(chunks)
File "/usr/lib/pymodules/python2.7/salt/state.py", line 1437, in call_chunks
running = self.call_chunk(low, running, chunks)
File "/usr/lib/pymodules/python2.7/salt/state.py", line 1562, in call_chunk
status = self.check_requisite(low, running, chunks, True)
File "/usr/lib/pymodules/python2.7/salt/state.py", line 1489, in check_requisite
if (fnmatch.fnmatch(chunk['name'], req_val) or
File "/usr/lib/python2.7/fnmatch.py", line 43, in fnmatch
return fnmatchcase(name, pat)
File "/usr/lib/python2.7/fnmatch.py", line 79, in fnmatchcase
return _cache[pat].match(name) is not None
TypeError: expected string or buffer

# Fixed code
def uncomment(name, regex, char="#", backup=".bak"):
    """
    Uncomment specified commented lines in a file

    name
        The full path to the file to be edited
    regex
        A regular expression used to find the lines that are to be uncommented.
        This regex should not include the comment character. A leading ``^``
        character will be stripped for convenience (for easily switching
        between comment() and uncomment()).  The regex will be searched for
        from the beginning of the line, ignoring leading spaces (we prepend
        '^[ \\t]*')
    char : ``#``
        The character to remove in order to uncomment a line
    backup : ``.bak``
        The file will be backed up before edit with this file extension;
        **WARNING:** each time ``sed``/``comment``/``uncomment`` is called will
        overwrite this backup

    Usage:

    .. code-block:: yaml

        /etc/adduser.conf:
          file.uncomment:
            - regex: EXTRA_GROUPS

    .. versionadded:: 0.9.5
    """
    ret = {"name": name, "changes": {}, "result": False, "comment": ""}
    if not name:
        return _error(ret, "Must provide name to file.uncomment")

    check_res, check_msg = _check_file(name)
    if not check_res:
        return _error(ret, check_msg)

    # Make sure the pattern appears in the file
    if __salt__["file.contains_regex_multiline"](
        name, "^[ \t]*{0}".format(regex.lstrip("^"))
    ):
        ret["comment"] = "Pattern already uncommented"
        ret["result"] = True
        return ret
    elif __salt__["file.contains_regex_multiline"](
        name, "{0}[ \t]*{1}".format(char, regex.lstrip("^"))
    ):
        # Line exists and is commented
        pass
    else:
        return _error(ret, "{0}: Pattern not found".format(regex))

    if __opts__["test"]:
        ret["comment"] = "File {0} is set to be updated".format(name)
        ret["result"] = None
        return ret

    with salt.utils.fopen(name, "rb") as fp_:
        slines = fp_.readlines()

    # Perform the edit
    __salt__["file.uncomment"](name, regex, char, backup)

    with salt.utils.fopen(name, "rb") as fp_:
        nlines = fp_.readlines()

    # Check the result
    ret["result"] = __salt__["file.contains_regex_multiline"](
        name, "^[ \t]*{0}".format(regex.lstrip("^"))
    )

    if slines != nlines:
        if not salt.utils.istextfile(name):
            ret["changes"]["diff"] = "Replace binary file"
        else:
            # Changes happened, add them
            ret["changes"]["diff"] = "".join(difflib.unified_diff(slines, nlines))

    if ret["result"]:
        ret["comment"] = "Uncommented lines successfully"
    else:
        ret["comment"] = "Expected uncommented lines not found"

    return ret