def attachfile(self, idlist, attachfile, description, **kwargs):
        if isinstance(attachfile, str):
            f = open(attachfile, "rb")
        elif hasattr(attachfile, 'read'):
            f = attachfile
        else:
            raise TypeError("attachfile must be filename or file-like object")
        if "contenttype" in kwargs:
            kwargs["content_type"] = kwargs.pop("contenttype")
        if "ispatch" in kwargs:
            kwargs["is_patch"] = kwargs.pop("ispatch")
        if "isprivate" in kwargs:
            kwargs["is_private"] = kwargs.pop("isprivate")
        if "filename" in kwargs:
            kwargs["file_name"] = kwargs.pop("filename")
        kwargs['summary'] = description
        data = f.read()
        if not isinstance(data, bytes):
            data = data.encode(locale.getpreferredencoding())
        kwargs['data'] = Binary(data)
        kwargs['ids'] = self._listify(idlist)
        if 'file_name' not in kwargs and hasattr(f, "name"):
            kwargs['file_name'] = os.path.basename(f.name)
        if 'content_type' not in kwargs:
            ctype = None
            if kwargs['file_name']:
                ctype = mimetypes.guess_type(
                    kwargs['file_name'], strict=False)[0]
            kwargs['content_type'] = ctype or 'application/octet-stream'
        ret = self._proxy.Bug.add_attachment(kwargs)
        if "attachments" in ret:
            ret = [int(k) for k in ret["attachments"].keys()]
        elif "ids" in ret:
            ret = ret["ids"]
        if isinstance(ret, list) and len(ret) == 1:
            ret = ret[0]
        return ret