# Buggy code
def serialize_spec(clonespec):
    """Serialize a clonespec or a relocation spec"""
    data = {}
    attrs = dir(clonespec)
    attrs = [x for x in attrs if not x.startswith("_")]
    for x in attrs:
        xo = getattr(clonespec, x)
        if callable(xo):
            continue
        xt = type(xo)
        if xo is None:
            data[x] = None
        elif issubclass(xt, list):
            data[x] = []
            for xe in xo:
                data[x].append(serialize_spec(xe))
        elif issubclass(xt, string_types + integer_types + (float, bool)):
            data[x] = xo
        elif issubclass(xt, dict):
            data[x] = {}
            for k, v in xo.items():
                data[x][k] = serialize_spec(v)
        elif isinstance(xo, vim.vm.ConfigSpec):
            data[x] = serialize_spec(xo)
        elif isinstance(xo, vim.vm.RelocateSpec):
            data[x] = serialize_spec(xo)
        elif isinstance(xo, vim.vm.device.VirtualDisk):
            data[x] = serialize_spec(xo)
        elif isinstance(xo, vim.Description):
            data[x] = {
                "dynamicProperty": serialize_spec(xo.dynamicProperty),
                "dynamicType": serialize_spec(xo.dynamicType),
                "label": serialize_spec(xo.label),
                "summary": serialize_spec(xo.summary),
            }
        elif hasattr(xo, "name"):
            data[x] = str(xo) + ":" + xo.name
        elif isinstance(xo, vim.vm.ProfileSpec):
            pass
        else:
            data[x] = str(xt)

    return data


# Traceback (TypeError)
The full traceback is:
Traceback (most recent call last):
File "/var/folders/pk/9q7j5zh54fqc8c24djnv1fv00000gn/T/ansible_3TGlLM/ansible_module_vmware_guest.py", line 1503, in <module>
main()
File "/var/folders/pk/9q7j5zh54fqc8c24djnv1fv00000gn/T/ansible_3TGlLM/ansible_module_vmware_guest.py", line 1497, in main
module.fail_json(**result)
File "/var/folders/pk/9q7j5zh54fqc8c24djnv1fv00000gn/T/ansible_3TGlLM/ansible_modlib.zip/ansible/module_utils/basic.py", line 2277, in fail_json
File "/var/folders/pk/9q7j5zh54fqc8c24djnv1fv00000gn/T/ansible_3TGlLM/ansible_modlib.zip/ansible/module_utils/basic.py", line 2255, in _return_formatted
File "/var/folders/pk/9q7j5zh54fqc8c24djnv1fv00000gn/T/ansible_3TGlLM/ansible_modlib.zip/ansible/module_utils/basic.py", line 509, in remove_values
File "/var/folders/pk/9q7j5zh54fqc8c24djnv1fv00000gn/T/ansible_3TGlLM/ansible_modlib.zip/ansible/module_utils/basic.py", line 448, in _remove_values_conditions
TypeError: 'vim.vm.device.VirtualDeviceSpec.FileOperation' object is not callable

fatal: [localhost]: FAILED! => {
"changed": false,
"failed": true,
"module_stderr": "Traceback (most recent call last):\n  File \"/var/folders/pk/9q7j5zh54fqc8c24djnv1fv00000gn/T/ansible_3TGlLM/ansible_module_vmware_guest.py\", line 1503, in <module>\n    main()\n  File \"/var/folders/pk/9q7j5zh54fqc8c24djnv1fv00000gn/T/ansible_3TGlLM/ansible_module_vmware_guest.py\", line 1497, in main\n    module.fail_json(**result)\n  File \"/var/folders/pk/9q7j5zh54fqc8c24djnv1fv00000gn/T/ansible_3TGlLM/ansible_modlib.zip/ansible/module_utils/basic.py\", line 2277, in fail_json\n  File \"/var/folders/pk/9q7j5zh54fqc8c24djnv1fv00000gn/T/ansible_3TGlLM/ansible_modlib.zip/ansible/module_utils/basic.py\", line 2255, in _return_formatted\n  File \"/var/folders/pk/9q7j5zh54fqc8c24djnv1fv00000gn/T/ansible_3TGlLM/ansible_modlib.zip/ansible/module_utils/basic.py\", line 509, in remove_values\n  File \"/var/folders/pk/9q7j5zh54fqc8c24djnv1fv00000gn/T/ansible_3TGlLM/ansible_modlib.zip/ansible/module_utils/basic.py\", line 448, in _remove_values_conditions\nTypeError: 'vim.vm.device.VirtualDeviceSpec.FileOperation' object is not callable\n",
"module_stdout": "",
"msg": "MODULE FAILURE",
"rc": 0
}

# Fixed code
def serialize_spec(clonespec):
    """Serialize a clonespec or a relocation spec"""
    data = {}
    attrs = dir(clonespec)
    attrs = [x for x in attrs if not x.startswith("_")]
    for x in attrs:
        xo = getattr(clonespec, x)
        if callable(xo):
            continue
        xt = type(xo)
        if xo is None:
            data[x] = None
        elif isinstance(xo, vim.vm.ConfigSpec):
            data[x] = serialize_spec(xo)
        elif isinstance(xo, vim.vm.RelocateSpec):
            data[x] = serialize_spec(xo)
        elif isinstance(xo, vim.vm.device.VirtualDisk):
            data[x] = serialize_spec(xo)
        elif isinstance(xo, vim.vm.device.VirtualDeviceSpec.FileOperation):
            data[x] = serialize_spec(xo)
        elif isinstance(xo, vim.Description):
            data[x] = {
                "dynamicProperty": serialize_spec(xo.dynamicProperty),
                "dynamicType": serialize_spec(xo.dynamicType),
                "label": serialize_spec(xo.label),
                "summary": serialize_spec(xo.summary),
            }
        elif hasattr(xo, "name"):
            data[x] = to_text(xo) + ":" + to_text(xo.name)
        elif isinstance(xo, vim.vm.ProfileSpec):
            pass
        elif issubclass(xt, list):
            data[x] = []
            for xe in xo:
                data[x].append(serialize_spec(xe))
        elif issubclass(xt, string_types + integer_types + (float, bool)):
            data[x] = to_text(xt)
        elif issubclass(xt, bool):
            data[x] = xo
        elif issubclass(xt, dict):
            data[to_text(x)] = {}
            for k, v in xo.items():
                k = to_text(k)
                data[x][k] = serialize_spec(v)
        else:
            data[x] = str(xt)

    return data