def PostOrPut(self, verb, data, uri, extra_headers=None, url_params=None, 
           escape_params=True, redirects_remaining=4, media_source=None, 
           converter=None):
    """Insert data into a GData service at the given URI.

    Args:
      verb: string, either 'POST' or 'PUT'
      data: string, ElementTree._Element, atom.Entry, or gdata.GDataEntry The
            XML to be sent to the uri. 
      uri: string The location (feed) to which the data should be inserted. 
           Example: '/base/feeds/items'. 
      extra_headers: dict (optional) HTTP headers which are to be included. 
                     The client automatically sets the Content-Type,
                     Authorization, and Content-Length headers.
      url_params: dict (optional) Additional URL parameters to be included
                  in the URI. These are translated into query arguments
                  in the form '&dict_key=value&...'.
                  Example: {'max-results': '250'} becomes &max-results=250
      escape_params: boolean (optional) If false, the calling code has already
                     ensured that the query will form a valid URL (all
                     reserved characters have been escaped). If true, this
                     method will escape the query and any URL parameters
                     provided.
      media_source: MediaSource (optional) Container for the media to be sent
          along with the entry, if provided.
      converter: func (optional) A function which will be executed on the 
          server's response. Often this is a function like 
          GDataEntryFromString which will parse the body of the server's 
          response and return a GDataEntry.

    Returns:
      If the post succeeded, this method will return a GDataFeed, GDataEntry,
      or the results of running converter on the server's result body (if
      converter was specified).
    """
    if extra_headers is None:
      extra_headers = {}

    if self.__gsessionid is not None:
      if 0 < uri.find('gsessionid='):
        if uri.find('?') > -1:
          uri += '&gsessionid=%s' % (self.__gsessionid,)
        else:
          uri += '?gsessionid=%s' % (self.__gsessionid,)

    if data and media_source:
      if ElementTree.iselement(data):
        data_str = ElementTree.tostring(data)
      else:
        data_str = str(data)
        
      multipart = []
      multipart.append('Media multipart posting\r\n--END_OF_PART\r\n' + \
          'Content-Type: application/atom+xml\r\n\r\n')
      multipart.append('\r\n--END_OF_PART\r\nContent-Type: ' + \
          media_source.content_type+'\r\n\r\n')
      multipart.append('\r\n--END_OF_PART--\r\n')
        
      extra_headers['MIME-version'] = '1.0'
      extra_headers['Content-Length'] = str(len(multipart[0]) +
          len(multipart[1]) + len(multipart[2]) +
          len(data_str) + media_source.content_length)

      extra_headers['Content-Type'] = 'multipart/related; boundary=END_OF_PART'
      server_response = self.request(verb, uri, 
          data=[multipart[0], data_str, multipart[1], media_source.file_handle,
              multipart[2]], headers=extra_headers)
      result_body = server_response.read()
      
    elif media_source or isinstance(data, gdata.MediaSource):
      if isinstance(data, gdata.MediaSource):
        media_source = data
      extra_headers['Content-Length'] = str(media_source.content_length)
      extra_headers['Content-Type'] = media_source.content_type
      server_response = self.request(verb, uri, 
          data=media_source.file_handle, headers=extra_headers)
      result_body = server_response.read()

    else:
      http_data = data
      content_type = 'application/atom+xml'
      extra_headers['Content-Type'] = content_type
      server_response = self.request(verb, uri, data=http_data,
          headers=extra_headers)
      result_body = server_response.read()

    # Server returns 201 for most post requests, but when performing a batch
    # request the server responds with a 200 on success.
    if server_response.status == 201 or server_response.status == 200:
      if converter:
        return converter(result_body)
      feed = gdata.GDataFeedFromString(result_body)
      if not feed:
        entry = gdata.GDataEntryFromString(result_body)
        if not entry:
          return result_body
        return entry
      return feed
    elif server_response.status == 302:
      if redirects_remaining > 0:
        location = server_response.getheader('Location')
        if location is not None:
          m = re.compile('[\?\&]gsessionid=(\w*)').search(location)
          if m is not None:
            self.__gsessionid = m.group(1) 
          return GDataService.PostOrPut(self, verb, data, location, 
              extra_headers, url_params, escape_params, 
              redirects_remaining - 1, media_source, converter=converter)
        else:
          raise RequestError, {'status': server_response.status,
              'reason': '302 received without Location header',
              'body': result_body}
      else:
        raise RequestError, {'status': server_response.status,
            'reason': 'Redirect received, but redirects_remaining <= 0',
            'body': result_body}
    else:
      raise RequestError, {'status': server_response.status,
          'reason': server_response.reason, 'body': result_body}
dataset/ETHPy150Open bradfitz/addressbooker/gdata/service.py/GDataService.PostOrPut/swapped operands of `<`