def xmlresponse(py_data):
    """
    Generates an XML formatted method response for the given python
    data.
    
    :param      py_data | <variant>
    """
    xroot = ElementTree.Element('methodResponse')
    xparams = ElementTree.SubElement(xroot, 'params')
    xparam = ElementTree.SubElement(xparams, 'param')

    type_map = {'bool': 'boolean',
                'float': 'double',
                'str': 'string',
                'unicode': 'string',
                'datetime': 'dateTime.iso8601',
                'date': 'date.iso8601',
                'time': 'time.iso8601'}

    def xobj(xparent, py_obj):
        # convert a list of information
        if type(py_obj) in (tuple, list):
            xarr = ElementTree.SubElement(xparent, 'array')
            xdata = ElementTree.SubElement(xarr, 'data')
            for val in py_obj:
                xval = ElementTree.SubElement(xdata, 'value')
                xobj(xval, val)

        # convert a dictionary of information
        elif type(py_obj) == dict:
            xstruct = ElementTree.SubElement(xparent, 'struct')
            for key, val in py_obj.items():
                xmember = ElementTree.SubElement(xstruct, 'member')
                xname = ElementTree.SubElement(xmember, 'name')
                xname.text = key
                xval = ElementTree.SubElement(xmember, 'value')
                xobj(xval, val)

        # convert a None value
        elif py_obj is None:
            ElementTree.SubElement(xparent, 'nil')

        # convert a basic value
        else:
            typ = type(py_obj).__name__
            typ = type_map.get(typ, typ)
            xitem = ElementTree.SubElement(xparent, typ)

            # convert a datetime/date/time
            if isinstance(py_obj, datetime.date) or \
                    isinstance(py_obj, datetime.time) or \
                    isinstance(py_obj, datetime.datetime):

                if py_obj.tzinfo and pytz:
                    data = py_obj.astimezone(pytz.utc).replace(tzinfo=None)
                    xitem.text = data.isoformat()
                else:
                    xitem.text = py_obj.isoformat()

            # convert a boolean
            elif type(py_obj) == bool:
                xitem.text = nstr(int(py_obj))

            # convert a non-string object
            elif not type(py_obj) in (str, unicode):
                xitem.text = nstr(py_obj)

            # convert a string object
            else:
                xitem.text = py_obj

    xobj(xparam, py_data)
    projex.text.xmlindent(xroot)
    return ElementTree.tostring(xroot)