Requests were crashing and returning strange results because the GIL
wasn't held in the callback that was creating python `bytes` instances
in the callback. Actually acquiring the gil, however, deadlocks.
So instead this keeps the future result as a C++ type and converts it to
python types when `get()` is called from Python.
- request_future works like request, but returns a wrapped std::future
instead of waiting on the future.
- request arguments now takes bytes instead of strings
- make the request "args" argument optional with a default of no data
parts.
- make request (and request_future().get()) return a vector of bytes
rather than strings (to avoid trying to utf8 decode).
- change connect and request to set an exception on failure rather than
an empty optional.
I tried taking a python function to log, but this results in nearly
immediately deadlock because of the gil, so for now just add one that
logs to stderr.