# Buggy code
def get_diff(
    self,
    candidate=None,
    running=None,
    diff_match="line",
    diff_ignore_lines=None,
    path=None,
    diff_replace="line",
):
    """
    Generate diff between candidate and running configuration. If the
    remote host supports onbox diff capabilities ie. supports_onbox_diff in that case
    candidate and running configurations are not required to be passed as argument.
    In case if onbox diff capability is not supported candidate argument is mandatory
    and running argument is optional.
    :param candidate: The configuration which is expected to be present on remote host.
    :param running: The base configuration which is used to generate diff.
    :param diff_match: Instructs how to match the candidate configuration with current device configuration
                  Valid values are 'line', 'strict', 'exact', 'none'.
                  'line' - commands are matched line by line
                  'strict' - command lines are matched with respect to position
                  'exact' - command lines must be an equal match
                  'none' - will not compare the candidate configuration with the running configuration
    :param diff_ignore_lines: Use this argument to specify one or more lines that should be
                              ignored during the diff.  This is used for lines in the configuration
                              that are automatically updated by the system.  This argument takes
                              a list of regular expressions or exact line matches.
    :param path: The ordered set of parents that uniquely identify the section or hierarchy
                 the commands should be checked against.  If the parents argument
                 is omitted, the commands are checked against the set of top
                level or global commands.
    :param diff_replace: Instructs on the way to perform the configuration on the device.
                    If the replace argument is set to I(line) then the modified lines are
                    pushed to the device in configuration mode.  If the replace argument is
                    set to I(block) then the entire command block is pushed to the device in
                    configuration mode if any line is not correct.
    :return: Configuration diff in  json format.
           {
               'config_diff': '',
               'banner_diff': {}
           }

    """
    diff = {}
    device_operations = self.get_device_operations()
    option_values = self.get_option_values()

    if candidate is None and device_operations["supports_generate_diff"]:
        raise ValueError("candidate configuration is required to generate diff")

    if diff_match not in option_values["diff_match"]:
        raise ValueError(
            "'match' value %s in invalid, valid values are %s"
            % (diff_match, ", ".join(option_values["diff_match"]))
        )

    if diff_replace not in option_values["diff_replace"]:
        raise ValueError(
            "'replace' value %s in invalid, valid values are %s"
            % (diff_replace, ", ".join(option_values["diff_replace"]))
        )

    # prepare candidate configuration
    candidate_obj = NetworkConfig(indent=1)
    want_src, want_banners = self._extract_banners(candidate)
    candidate_obj.load(want_src)

    if running and diff_match != "none":
        # running configuration
        have_src, have_banners = self._extract_banners(running)
        running_obj = NetworkConfig(
            indent=1, contents=have_src, ignore_lines=diff_ignore_lines
        )
        configdiffobjs = candidate_obj.difference(
            running_obj, path=path, match=diff_match, replace=diff_replace
        )

    else:
        configdiffobjs = candidate_obj.items
        have_banners = {}

    diff["config_diff"] = dumps(configdiffobjs, "commands") if configdiffobjs else ""
    banners = self._diff_banners(want_banners, have_banners)
    diff["banner_diff"] = banners if banners else {}
    return diff


# Traceback (TypeError)
TASK [azure_load_balancer : Get lbs] *********************************************************************************************
task path: /home/vmadmin/cluster_build/roles/azure_load_balancer/tasks/main.yaml:15
Using module file /home/vmadmin/.local/lib/python2.7/site-packages/ansible/modules/cloud/azure/azure_rm_loadbalancer_facts.py
<localhost> ESTABLISH LOCAL CONNECTION FOR USER: vmadmin
<localhost> EXEC /bin/sh -c 'echo ~ &amp;&amp; sleep 0'
<localhost> EXEC /bin/sh -c '( umask 77 &amp;&amp; mkdir -p "` echo /home/vmadmin/.ansible/tmp/ansible-tmp-1504708358.3-41710485333814 `" &amp;&amp; echo ansible-tmp-1504708358.3-41710485333814="` echo /home/vmadmin/.ansible/tmp/ansible-tmp-1504708358.3-41710485333814 `" ) &amp;&amp; sleep 0'
<localhost> PUT /tmp/tmpy_CiqC TO /home/vmadmin/.ansible/tmp/ansible-tmp-1504708358.3-41710485333814/azure_rm_loadbalancer_facts.py
<localhost> EXEC /bin/sh -c 'chmod u+x /home/vmadmin/.ansible/tmp/ansible-tmp-1504708358.3-41710485333814/ /home/vmadmin/.ansible/tmp/ansible-tmp-1504708358.3-41710485333814/azure_rm_loadbalancer_facts.py &amp;&amp; sleep 0'
<localhost> EXEC /bin/sh -c '/usr/bin/python /home/vmadmin/.ansible/tmp/ansible-tmp-1504708358.3-41710485333814/azure_rm_loadbalancer_facts.py; rm -rf "/home/vmadmin/.ansible/tmp/ansible-tmp-1504708358.3-41710485333814/" > /dev/null 2>&amp;1 &amp;&amp; sleep 0'
The full traceback is:
Traceback (most recent call last):
File "/tmp/ansible_VTaHxN/ansible_module_azure_rm_loadbalancer_facts.py", line 180, in <module>
main()
File "/tmp/ansible_VTaHxN/ansible_module_azure_rm_loadbalancer_facts.py", line 177, in main
AzureRMLoadBalancerFacts()
File "/tmp/ansible_VTaHxN/ansible_module_azure_rm_loadbalancer_facts.py", line 123, in __init__
facts_module=True
File "/tmp/ansible_VTaHxN/ansible_modlib.zip/ansible/module_utils/azure_rm_common.py", line 255, in __init__
File "/tmp/ansible_VTaHxN/ansible_module_azure_rm_loadbalancer_facts.py", line 133, in exec_module
else self.list_items()
File "/tmp/ansible_VTaHxN/ansible_module_azure_rm_loadbalancer_facts.py", line 162, in list_items
response = self.network_client.load_balancers.list()
TypeError: list() takes at least 2 arguments (1 given)

fatal: [localhost]: FAILED! => {
"changed": false,
"failed": true,
"module_stderr": "Traceback (most recent call last):\n  File \"/tmp/ansible_VTaHxN/ansible_module_azure_rm_loadbalancer_facts.py\", line 180, in <module>\n    main()\n  File \"/tmp/ansible_VTaHxN/ansible_module_azure_rm_loadbalancer_facts.py\", line 177, in main\n    AzureRMLoadBalancerFacts()\n  File \"/tmp/ansible_VTaHxN/ansible_module_azure_rm_loadbalancer_facts.py\", line 123, in __init__\n    facts_module=True\n  File \"/tmp/ansible_VTaHxN/ansible_modlib.zip/ansible/module_utils/azure_rm_common.py\", line 255, in __init__\n  File \"/tmp/ansible_VTaHxN/ansible_module_azure_rm_loadbalancer_facts.py\", line 133, in exec_module\n    else self.list_items()\n  File \"/tmp/ansible_VTaHxN/ansible_module_azure_rm_loadbalancer_facts.py\", line 162, in list_items\n    response = self.network_client.load_balancers.list()\nTypeError: list() takes at least 2 arguments (1 given)\n",
"module_stdout": "",
"msg": "MODULE FAILURE",
"rc": 0
}

# Fixed code
def get_diff(
    self,
    candidate=None,
    running=None,
    diff_match="line",
    diff_ignore_lines=None,
    path=None,
    diff_replace="line",
):
    """
    Generate diff between candidate and running configuration. If the
    remote host supports onbox diff capabilities ie. supports_onbox_diff in that case
    candidate and running configurations are not required to be passed as argument.
    In case if onbox diff capability is not supported candidate argument is mandatory
    and running argument is optional.
    :param candidate: The configuration which is expected to be present on remote host.
    :param running: The base configuration which is used to generate diff.
    :param diff_match: Instructs how to match the candidate configuration with current device configuration
                  Valid values are 'line', 'strict', 'exact', 'none'.
                  'line' - commands are matched line by line
                  'strict' - command lines are matched with respect to position
                  'exact' - command lines must be an equal match
                  'none' - will not compare the candidate configuration with the running configuration
    :param diff_ignore_lines: Use this argument to specify one or more lines that should be
                              ignored during the diff.  This is used for lines in the configuration
                              that are automatically updated by the system.  This argument takes
                              a list of regular expressions or exact line matches.
    :param path: The ordered set of parents that uniquely identify the section or hierarchy
                 the commands should be checked against.  If the parents argument
                 is omitted, the commands are checked against the set of top
                level or global commands.
    :param diff_replace: Instructs on the way to perform the configuration on the device.
                    If the replace argument is set to I(line) then the modified lines are
                    pushed to the device in configuration mode.  If the replace argument is
                    set to I(block) then the entire command block is pushed to the device in
                    configuration mode if any line is not correct.
    :return: Configuration diff in  json format.
           {
               'config_diff': '',
               'banner_diff': {}
           }

    """
    diff = {}
    device_operations = self.get_device_operations()
    option_values = self.get_option_values()

    if candidate is None and device_operations["supports_generate_diff"]:
        raise ValueError("candidate configuration is required to generate diff")

    if diff_match not in option_values["diff_match"]:
        raise ValueError(
            "'match' value %s in invalid, valid values are %s"
            % (diff_match, ", ".join(option_values["diff_match"]))
        )

    if diff_replace not in option_values["diff_replace"]:
        raise ValueError(
            "'replace' value %s in invalid, valid values are %s"
            % (diff_replace, ", ".join(option_values["diff_replace"]))
        )

    # prepare candidate configuration
    candidate_obj = NetworkConfig(indent=1, ignore_lines=diff_ignore_lines)
    want_src, want_banners = self._extract_banners(candidate)
    candidate_obj.load(want_src)

    if running and diff_match != "none":
        # running configuration
        have_src, have_banners = self._extract_banners(running)
        running_obj = NetworkConfig(
            indent=1, contents=have_src, ignore_lines=diff_ignore_lines
        )
        configdiffobjs = candidate_obj.difference(
            running_obj, path=path, match=diff_match, replace=diff_replace
        )

    else:
        configdiffobjs = candidate_obj.items
        have_banners = {}

    diff["config_diff"] = dumps(configdiffobjs, "commands") if configdiffobjs else ""
    banners = self._diff_banners(want_banners, have_banners)
    diff["banner_diff"] = banners if banners else {}
    return diff