# Buggy code
def build_xml(container, xmap=None, params=None, opcode=None):
    """
    Builds netconf xml rpc document from meta-data

    Args:
        container: the YANG container within the namespace
        xmap: meta-data map to build xml tree
        params: Input params that feed xml tree values
        opcode: operation to be performed (merge, delete etc.)

    Example:
        Module inputs:
            banner_params = [{'banner':'motd', 'text':'Ansible banner example', 'state':'present'}]

        Meta-data definition:
            bannermap = collections.OrderedDict()
            bannermap.update([
                ('banner', {'xpath' : 'banners/banner', 'tag' : True, 'attrib' : "operation"}),
                ('a:banner', {'xpath' : 'banner/banner-name'}),
                ('a:text', {'xpath' : 'banner/banner-text', 'operation' : 'edit'})
            ])

            Fields:
                key: exact match to the key in arg_spec for a parameter
                   (prefixes --> a: value fetched from arg_spec, m: value fetched from meta-data)
                xpath: xpath of the element (based on YANG model)
                tag: True if no text on the element
                attrib: attribute to be embedded in the element (e.g. xc:operation="merge")
                operation: if edit --> includes the element in edit_config() query else ignores for get() queries
                value: if key is prefixed with "m:", value is required in meta-data

        Output:
            <config xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
              <banners xmlns="http://cisco.com/ns/yang/Cisco-IOS-XR-infra-infra-cfg">
                <banner xc:operation="merge">
                  <banner-name>motd</banner-name>
                  <banner-text>Ansible banner example</banner-text>
                </banner>
              </banners>
            </config>
    :returns: xml rpc document as a string
    """

    if opcode == "filter":
        root = etree.Element("filter", type="subtree")
    elif opcode in ("delete", "merge"):
        root = etree.Element("config", nsmap=NS_DICT["BASE_NSMAP"])

    container_ele = etree.SubElement(
        root, container, nsmap=NS_DICT[container.upper() + "_NSMAP"]
    )

    if xmap is not None:
        if params is None:
            build_xml_subtree(container_ele, xmap, opcode=opcode)
        else:
            subtree_list = list()
            for param in to_list(params):
                subtree_ele = build_xml_subtree(
                    container_ele, xmap, param=param, opcode=opcode
                )
                if subtree_ele is not None:
                    subtree_list.append(subtree_ele)

            for item in subtree_list:
                container_ele.append(item)

    return etree.tostring(root, encoding="unicode")


# 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 build_xml(container, xmap=None, params=None, opcode=None):
    """
    Builds netconf xml rpc document from meta-data

    Args:
        container: the YANG container within the namespace
        xmap: meta-data map to build xml tree
        params: Input params that feed xml tree values
        opcode: operation to be performed (merge, delete etc.)

    Example:
        Module inputs:
            banner_params = [{'banner':'motd', 'text':'Ansible banner example', 'state':'present'}]

        Meta-data definition:
            bannermap = collections.OrderedDict()
            bannermap.update([
                ('banner', {'xpath' : 'banners/banner', 'tag' : True, 'attrib' : "operation"}),
                ('a:banner', {'xpath' : 'banner/banner-name'}),
                ('a:text', {'xpath' : 'banner/banner-text', 'operation' : 'edit'})
            ])

            Fields:
                key: exact match to the key in arg_spec for a parameter
                   (prefixes --> a: value fetched from arg_spec, m: value fetched from meta-data)
                xpath: xpath of the element (based on YANG model)
                tag: True if no text on the element
                attrib: attribute to be embedded in the element (e.g. xc:operation="merge")
                operation: if edit --> includes the element in edit_config() query else ignores for get() queries
                value: if key is prefixed with "m:", value is required in meta-data

        Output:
            <config xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
              <banners xmlns="http://cisco.com/ns/yang/Cisco-IOS-XR-infra-infra-cfg">
                <banner xc:operation="merge">
                  <banner-name>motd</banner-name>
                  <banner-text>Ansible banner example</banner-text>
                </banner>
              </banners>
            </config>
    :returns: xml rpc document as a string
    """
    if opcode == "filter":
        root = etree.Element("filter", type="subtree")
    elif opcode in ("delete", "merge"):
        root = etree.Element("config", nsmap=NS_DICT["BASE_NSMAP"])

    container_ele = etree.SubElement(
        root, container, nsmap=NS_DICT[container.upper() + "_NSMAP"]
    )

    if xmap is not None:
        if params is None:
            build_xml_subtree(container_ele, xmap, opcode=opcode)
        else:
            subtree_list = list()
            for param in to_list(params):
                subtree_ele = build_xml_subtree(
                    container_ele, xmap, param=param, opcode=opcode
                )
                if subtree_ele is not None:
                    subtree_list.append(subtree_ele)

            for item in subtree_list:
                container_ele.append(item)

    return etree.tostring(root, encoding="unicode")