# Buggy code
def check_declarative_intent_params(module, want, result):
    failed_conditions = []
    have_neighbors = None
    for w in want:
        want_state = w.get("state")
        want_tx_rate = w.get("tx_rate")
        want_rx_rate = w.get("rx_rate")
        want_neighbors = w.get("neighbors")

        if (
            want_state not in ("up", "down")
            and not want_tx_rate
            and not want_rx_rate
            and not want_neighbors
        ):
            continue

        if result["changed"]:
            sleep(w["delay"])

        command = "show interfaces %s" % w["name"]
        output = run_commands(module, [command])

        if want_state in ("up", "down"):
            match = re.search(r"%s (\w+)" % "line protocol is", output[0], re.M)
            have_state = None
            if match:
                have_state = match.group(1)
            if have_state is None or not conditional(want_state, have_state.strip()):
                failed_conditions.append("state " + "eq(%s)" % want_state)

        if want_tx_rate:
            match = re.search(r"%s (\d+)" % "output rate", output[0], re.M)
            have_tx_rate = None
            if match:
                have_tx_rate = match.group(1)

            if have_tx_rate is None or not conditional(
                want_tx_rate, have_tx_rate.strip(), cast=int
            ):
                failed_conditions.append("tx_rate " + want_tx_rate)

        if want_rx_rate:
            match = re.search(r"%s (\d+)" % "input rate", output[0], re.M)
            have_rx_rate = None
            if match:
                have_rx_rate = match.group(1)

            if have_rx_rate is None or not conditional(
                want_rx_rate, have_rx_rate.strip(), cast=int
            ):
                failed_conditions.append("rx_rate " + want_rx_rate)

        if want_neighbors:
            have_host = []
            have_port = []
            if have_neighbors is None:
                have_neighbors = run_commands(
                    module, ["show lldp neighbors {}".format(w["name"])]
                )

            if have_neighbors[0]:
                lines = have_neighbors[0].strip().split("\n")
                col = None
                for index, line in enumerate(lines):
                    if re.search(
                        r"^Port\s+Neighbor Device ID\s+Neighbor Port ID\s+TTL", line
                    ):
                        col = index
                        break

                if col and col < len(lines) - 1:
                    for items in lines[col + 1 :]:
                        value = re.split(r"\s+", items)
                        try:
                            have_port.append(value[2])
                            have_host.append(value[1])
                        except IndexError:
                            pass

            for item in want_neighbors:
                host = item.get("host")
                port = item.get("port")
                if host and host not in have_host:
                    failed_conditions.append("host " + host)
                if port and port not in have_port:
                    failed_conditions.append("port " + port)
    return failed_conditions


# Traceback (TypeError)
TASK [Check intent arguments] **********************************************************************************
task path: /Users/david/code/test/eos.yaml:8
<eos02> connection transport is eapi
Using module file /Users/david/code/ansible/lib/ansible/modules/network/eos/eos_interface.py
<eos02> ESTABLISH LOCAL CONNECTION FOR USER: david
<eos02> EXEC /bin/sh -c 'echo ~ &amp;&amp; sleep 0'
<eos02> EXEC /bin/sh -c '( umask 77 &amp;&amp; mkdir -p "` echo /Users/david/.ansible/tmp/ansible-tmp-1519930473.54-89724812253350 `" &amp;&amp; echo ansible-tmp-1519930473.54-89724812253350="` echo /Users/david/.ansible/tmp/ansible-tmp-1519930473.54-89724812253350 `" ) &amp;&amp; sleep 0'
<eos02> PUT /Users/david/.ansible/tmp/ansible-local-199917TML_E/tmpgccdUR TO /Users/david/.ansible/tmp/ansible-tmp-1519930473.54-89724812253350/eos_interface.py
<eos02> EXEC /bin/sh -c 'chmod u+x /Users/david/.ansible/tmp/ansible-tmp-1519930473.54-89724812253350/ /Users/david/.ansible/tmp/ansible-tmp-1519930473.54-89724812253350/eos_interface.py &amp;&amp; sleep 0'
<eos02> EXEC /bin/sh -c '/usr/bin/python /Users/david/.ansible/tmp/ansible-tmp-1519930473.54-89724812253350/eos_interface.py &amp;&amp; sleep 0'
<eos02> EXEC /bin/sh -c 'rm -f -r /Users/david/.ansible/tmp/ansible-tmp-1519930473.54-89724812253350/ > /dev/null 2>&amp;1 &amp;&amp; sleep 0'
The full traceback is:
Traceback (most recent call last):
File "/var/folders/x6/l9cfl1bs7x9_h9_v5sn94z640000gn/T/ansible_Glr2s3/ansible_module_eos_interface.py", line 466, in <module>
main()
File "/var/folders/x6/l9cfl1bs7x9_h9_v5sn94z640000gn/T/ansible_Glr2s3/ansible_module_eos_interface.py", line 456, in main
failed_conditions = check_declarative_intent_params(module, want, result)
File "/var/folders/x6/l9cfl1bs7x9_h9_v5sn94z640000gn/T/ansible_Glr2s3/ansible_module_eos_interface.py", line 337, in check_declarative_intent_params
match = re.search(r'%s (\w+)' % 'line protocol is', output[0], re.M)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/re.py", line 146, in search
return _compile(pattern, flags).search(string)
TypeError: expected string or buffer

fatal: [eos02]: FAILED! => {
"changed": false,
"module_stderr": "Traceback (most recent call last):\n  File \"/var/folders/x6/l9cfl1bs7x9_h9_v5sn94z640000gn/T/ansible_Glr2s3/ansible_module_eos_interface.py\", line 466, in <module>\n    main()\n  File \"/var/folders/x6/l9cfl1bs7x9_h9_v5sn94z640000gn/T/ansible_Glr2s3/ansible_module_eos_interface.py\", line 456, in main\n    failed_conditions = check_declarative_intent_params(module, want, result)\n  File \"/var/folders/x6/l9cfl1bs7x9_h9_v5sn94z640000gn/T/ansible_Glr2s3/ansible_module_eos_interface.py\", line 337, in check_declarative_intent_params\n    match = re.search(r'%s (\\w+)' % 'line protocol is', output[0], re.M)\n  File \"/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/re.py\", line 146, in search\n    return _compile(pattern, flags).search(string)\nTypeError: expected string or buffer\n",
"module_stdout": "",
"msg": "MODULE FAILURE",
"rc": 1
}

# Fixed code
def check_declarative_intent_params(module, want, result):
    failed_conditions = []
    have_neighbors = None
    for w in want:
        want_state = w.get("state")
        want_tx_rate = w.get("tx_rate")
        want_rx_rate = w.get("rx_rate")
        want_neighbors = w.get("neighbors")

        if (
            want_state not in ("up", "down")
            and not want_tx_rate
            and not want_rx_rate
            and not want_neighbors
        ):
            continue

        if result["changed"]:
            sleep(w["delay"])

        command = {"command": "show interfaces %s" % w["name"], "output": "text"}
        output = run_commands(module, [command])

        if want_state in ("up", "down"):
            match = re.search(r"%s (\w+)" % "line protocol is", output[0], re.M)
            have_state = None
            if match:
                have_state = match.group(1)
            if have_state is None or not conditional(want_state, have_state.strip()):
                failed_conditions.append("state " + "eq(%s)" % want_state)

        if want_tx_rate:
            match = re.search(r"%s (\d+)" % "output rate", output[0], re.M)
            have_tx_rate = None
            if match:
                have_tx_rate = match.group(1)

            if have_tx_rate is None or not conditional(
                want_tx_rate, have_tx_rate.strip(), cast=int
            ):
                failed_conditions.append("tx_rate " + want_tx_rate)

        if want_rx_rate:
            match = re.search(r"%s (\d+)" % "input rate", output[0], re.M)
            have_rx_rate = None
            if match:
                have_rx_rate = match.group(1)

            if have_rx_rate is None or not conditional(
                want_rx_rate, have_rx_rate.strip(), cast=int
            ):
                failed_conditions.append("rx_rate " + want_rx_rate)

        if want_neighbors:
            have_host = []
            have_port = []
            if have_neighbors is None:
                command = {
                    "command": "show lldp neighbors {}".format(w["name"]),
                    "output": "text",
                }
                have_neighbors = run_commands(module, [command])

            if have_neighbors[0]:
                lines = have_neighbors[0].strip().split("\n")
                col = None
                for index, line in enumerate(lines):
                    if re.search(
                        r"^Port\s+Neighbor Device ID\s+Neighbor Port ID\s+TTL", line
                    ):
                        col = index
                        break

                if col and col < len(lines) - 1:
                    for items in lines[col + 1 :]:
                        value = re.split(r"\s+", items)
                        try:
                            have_port.append(value[2])
                            have_host.append(value[1])
                        except IndexError:
                            pass

            for item in want_neighbors:
                host = item.get("host")
                port = item.get("port")
                if host and host not in have_host:
                    failed_conditions.append("host " + host)
                if port and port not in have_port:
                    failed_conditions.append("port " + port)
    return failed_conditions