Support for bytearray when creating Request with files argument, just like str and bytes.

When creating a Request with files argument, the "fp" part of a file entry can currently be either (a) a str, (b) a bytes, or (c) any other object that has a .read() method that returns data. For str or bytes,  StringIO or ByteIO wrapper-objects are created.
When building data in-memory, a bytearray is often more convenient and memory efficient compared to immutable bytes.

This simple change allows models.RequestEncodingMixin._encode_files method to use bytearray as fp in addition to the currently supported bytes and str input. This means that users do not have to worry about creating a ByteIO object. 

I've seen requests users creating bytes-objects from bytearrays before passing it to requests. This, of course, doubles the memory consumption and is completely unnecessary. Yes, the correct approach from the user's side would be to create a ByteIO object (instead of bytes). But not all users seem to be aware of this. Letting requests take bytearrays means that it would "just work", when the user passes these to requests, and thus avoids the potential pitfall where a user just says "requests chokes on bytearrays, so convert to str." (Actual comment from pyzotero, a principal python client module to consume Zotero's REST API).

I'm not sure if this simple change requires it's own test, but I've added one just in case. It also tests for bytes objects, which was not covered by the existing test, test_can_send_nonstring_objects_with_files. Perhaps I should just expand test_can_send_nonstring_objects_with_files to also cover bytes and bytearray? It currently only covers str (which are, of course, also bytes in python 2).

The test suite currently does fail in TestMorselToCookieExpires.test_expires_valid_str; however this is unrelated to this change and was also failing before, in commit 461b740d.

Compatability: bytearray and the byte literal (used in the test) are both available in python 2.6 and forward.

Let me know if there is anything else that you would need in order to accept this pull request.


This looks great, I see no reason not to merge this. :cake:

@sigmavirus24, I'll let you pull the trigger.


After further thought, I'm thinking maybe it would be better to just use the str/bytes/bytearray object that the user provided directly? This would cut the number of in-memory file data copies from 3 to 1. E.g.

```
if isinstance(fp, (str, bytes, bytearray)):
    data = fp
else:
    data = fp.read()
```

For reference, the existing code with annotation of the created copies:

```
# We already have one copy of the file data, provided by the user
if isinstance(fp, str):
    fp = StringIO(fp)
if isinstance(fp, (bytes, bytearray)):
    fp = BytesIO(fp)    # 2nd copy

rf = RequestField(name=k, data=fp.read(), # calling fp.read() creates a 3rd copy.
                  filename=fn, headers=fh)
```

The data is not modified down stream, only used in `encode_multipart_formdata` as:

```
body.write(data)
```

So it should be ok to use the data copy that the user provided.


Hi, 
I've updated the test case to use string input rather than float. The test case is just a modified version of test_can_send_nonstring_objects_with_files, which had (and still has) float input, data = {'a': 0.0}.


Regarding my previous note on reducing the number of copies created by the use of BytesIO and StringIO: This is apparently going to be addressed in Python 3.5, where BytesIO will only create a copy of the initial data when it is changed: http://bugs.python.org/issue22003.
I'm not really sure whether fp.read() will then also just return the original data, or if it will return a copy.


Thanks @scholer! :cake: 


Thank you for accepting my pull request, @sigmavirus24  :)