# Buggy code
def comment(name, regex, char="#", backup=".bak"):
    """
    Comment out specified 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 commented;
        this pattern will be wrapped in parenthesis and will move any
        preceding/trailing ``^`` or ``$`` characters outside the parenthesis
        (e.g., the pattern ``^foo$`` will be rewritten as ``^(foo)$``)
        Note that you _need_ the leading ^, otherwise each time you run
        highstate, another comment char will be inserted.
    char : ``#``
        The character to be inserted at the beginning of a line in order to
        comment it out
    backup : ``.bak``
        The file will be backed up before edit with this file extension

        .. warning::

            This backup will be overwritten each time ``sed`` / ``comment`` /
            ``uncomment`` is called. Meaning the backup will only be useful
            after the first invocation.

    Usage:

    .. code-block:: yaml

        /etc/fstab:
          file.comment:
            - regex: ^bind 127.0.0.1

    .. 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)

    unanchor_regex = regex.lstrip("^").rstrip("$")

    # Make sure the pattern appears in the file before continuing
    if not __salt__["file.contains_regex_multiline"](name, regex):
        if __salt__["file.contains_regex_multiline"](name, unanchor_regex):
            ret["comment"] = "Pattern already commented"
            ret["result"] = True
            return ret
        else:
            return _error(ret, "{0}: Pattern not found".format(unanchor_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.comment"](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, unanchor_regex)

    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"] = "Commented lines successfully"
    else:
        ret["comment"] = "Expected commented 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 comment(name, regex, char="#", backup=".bak"):
    """
    Comment out specified 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 commented;
        this pattern will be wrapped in parenthesis and will move any
        preceding/trailing ``^`` or ``$`` characters outside the parenthesis
        (e.g., the pattern ``^foo$`` will be rewritten as ``^(foo)$``)
        Note that you _need_ the leading ^, otherwise each time you run
        highstate, another comment char will be inserted.
    char : ``#``
        The character to be inserted at the beginning of a line in order to
        comment it out
    backup : ``.bak``
        The file will be backed up before edit with this file extension

        .. warning::

            This backup will be overwritten each time ``sed`` / ``comment`` /
            ``uncomment`` is called. Meaning the backup will only be useful
            after the first invocation.

    Usage:

    .. code-block:: yaml

        /etc/fstab:
          file.comment:
            - regex: ^bind 127.0.0.1

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

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

    unanchor_regex = regex.lstrip("^").rstrip("$")

    # Make sure the pattern appears in the file before continuing
    if not __salt__["file.contains_regex_multiline"](name, regex):
        if __salt__["file.contains_regex_multiline"](name, unanchor_regex):
            ret["comment"] = "Pattern already commented"
            ret["result"] = True
            return ret
        else:
            return _error(ret, "{0}: Pattern not found".format(unanchor_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.comment"](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, unanchor_regex)

    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"] = "Commented lines successfully"
    else:
        ret["comment"] = "Expected commented lines not found"

    return ret