def diff_map(self, intype):
        stmts = []
        if not hasattr(intype, 'attributes'):
            raise KeyError("Composite '%s' has no attributes" % intype.name)
        attrnames = [attr.name for attr in self.attributes
                     if not hasattr(attr, 'dropped')]
        dbattrs = len(attrnames)

        base = "ALTER TYPE %s\n    " % (self.qualname())
        # check input attributes
        for (num, inattr) in enumerate(intype.attributes):
            if hasattr(inattr, 'oldname'):
                assert(self.attributes[num].name == inattr.oldname)
                stmts.append(self.attributes[num].rename(inattr.name))
            # check existing attributes
            if num < dbattrs and self.attributes[num].name == inattr.name:
                (stmt, descr) = self.attributes[num].diff_map(inattr)
                if stmt:
                    stmts.append(base + stmt)
                if descr:
                    stmts.append(descr)
            # add new attributes
            elif inattr.name not in attrnames:
                (stmt, descr) = inattr.add()
                stmts.append(base + "ADD ATTRIBUTE %s" % stmt)
                if descr:
                    stmts.append(descr)

        if intype.owner is not None:
            if intype.owner != self.owner:
                stmts.append(self.alter_owner(intype.owner))
        stmts.append(self.diff_description(intype))

        return stmts
decorator the get child messages to indicate errors
dataset/ETHPy150Open perseas/Pyrseas/pyrseas/dbobject/dbtype.py/Composite.diff_map--crossover with--dataset/ETHPy150Open OrbitzWorldwide/droned/droned/services/remote_config.py/resource_error