docs: def encode_params(self, data=None, files=None, **kwargs):
          """
          Build the body for a multipart/form-data request.
          Will successfully encode files when passed as a dict or a list of
          tuples. Order is retained if data is a list of tuples but arbitrary
          if parameters are supplied as a dict.
          The tuples may be string (filepath), 2-tuples (filename, fileobj), 3-tuples (filename, fileobj, contentype)
          or 4-tuples (filename, fileobj, contentype, custom_headers).
          """
          if isinstance(data, basestring):
              raise ValueError("Data must not be a string.")
  
          # optional args
          boundary = kwargs.get("boundary", None)
          output_str = kwargs.get("output_str", self.output_str)
  
          new_fields = []
          fields = to_key_val_list(data or {})
          files = to_key_val_list(files or {})
  
          for field, value in fields:
              ctype = None
              if isinstance(value, (tuple, list)) and len(value) == 2:
                  val, ctype = value
              else:
                  val = value
  
              if isinstance(val, basestring) or not hasattr(val, '__iter__'):
                  val = [val]
              for v in val:
                  # Don't call str() on bytestrings: in Py3 it all goes wrong.
                  if not isinstance(v, bytes):
                      v = to_string(v, lang=output_str)
  
                  field = field.decode('utf-8') if isinstance(field, bytes) else field
                  v = v.encode('utf-8') if isinstance(v, str) else v
  
                  rf = RequestField(name=field, data=v)
                  rf.make_multipart(content_type=ctype)
                  new_fields.append(rf)
  
          for (k, v) in files:
              fn, fdata, ft, fh = guess_file_name_stream_type_header(v)
              rf = RequestField(name=k, data=fdata, filename=fn, headers=fh)
              rf.make_multipart(content_type=ft)
              new_fields.append(rf)
  
          if boundary is None:
              boundary = self.boundary
          body, content_type = encode_multipart_formdata(new_fields, boundary=boundary)
  
          return body, content_type