'Attach an attachment to an issue and returns a Resource for it.
The client will *not* attempt to open or validate the attachment; it expects a file-like object to be ready
for its use. The user is still responsible for tidying up (e.g., closing the file, killing the socket, etc.)
:param issue: the issue to attach the attachment to
:param attachment: file-like object to attach to the issue, also works if it is a string with the filename.
:param filename: optional name for the attached file. If omitted, the file object\'s ``name`` attribute
is used. If you aquired the file-like object by any other method than ``open()``, make sure
that a name is specified in one way or the other.
:rtype: an Attachment Resource'

@translate_resource_args
def add_attachment(self, issue, attachment, filename=None):

    if isinstance(attachment, string_types):
        attachment = open(attachment, u'rb')
    if (hasattr(attachment, u'read') and hasattr(attachment, u'mode') and (attachment.mode != u'rb')):
        logging.warning((u"%s    was    not    opened    in    'rb'    mode,    attaching    file    may    fail." % attachment.name))
    url = self._get_url(((u'issue/' + str(issue)) + u'/attachments'))
    fname = filename
    if (not fname):
        fname = os.path.basename(attachment.name)
    if (u'MultipartEncoder' not in globals()):
        method = u'old'
        r = self._session.post(url, files={u'file': (fname, attachment, u'application/octet-stream')}, headers=CaseInsensitiveDict({u'content-type': None, u'X-Atlassian-Token': u'nocheck'}))
    else:
        method = u'MultipartEncoder'
        def file_stream():
            return MultipartEncoder(fields={u'file': (fname, attachment, u'application/octet-stream')})
        m = file_stream()
        r = self._session.post(url, data=m, headers=CaseInsensitiveDict({u'content-type': m.content_type, u'X-Atlassian-Token': u'nocheck'}), retry_data=file_stream)
    js = json_loads(r)
    if ((not js) or (not isinstance(js, collections.Iterable))):
        raise JIRAError((u'Unable    to    parse    JSON:    %s' % js))
    attachment = Attachment(self._options, self._session, js[0])
    if (attachment.size == 0):
        raise JIRAError((u'Added    empty    attachment    via    %s    method?!:    r:    %s\nattachment:    %s' % (method, r, attachment)))
    return attachment
