With HTTPResponse body set to string, "ValueError: Unable to determine whether fp is closed"

I'm doing something like

```
headers = {'a dict':'test'}
body = 'some string'
http_resp = HTTPResponse(body=body,
                         headers=headers,
                         status=202,
                         version=0,
                         reason='Ok',
                         decode_content=False)

response = Response()

# Fallback to None if there's no status_code, for whatever reason.
response.status_code = getattr(http_resp, 'status', None)
response.encoding = get_encoding_from_headers(headers)
response.raw = http_resp
response.reason = response.raw.reason
response.url = url
# Hack to avoid ValueError on fp check (bug?)
response._content = response.raw._body

print response.content
```

The hack portion is required because I get a ValueError otherwise in the stream method:

```
while not is_fp_closed(self._fp)
```

Seems like there needs to be an exit on a stringish body.


You're mucking around in urllib3 internals. This should be filed over at [urllib3](/shazow/urllib3).


As an aside, if you're mucking around with urllib3 responses for testing purposes, take a look at how it's done in [betamax](/sigmavirus24/betamax).


I wouldn't call it mucking, but I think it's questionable whether requests should be calling the stream method when there's no file-like content... regardless of whether the is_fp_closed method in urllib is buggy or not.


Rather than provide urllib3 objects in this case, requests should let you just provide a file-like object as the underlying response. That should work absolutely fine.


To add context, I'm wrapping a third-party proxy-like service as a drop-in (ish) replacement for requests.  In order to do so, I have to fork over a Response object.

My first thought was to wrap my string in a StringIO object; but when I do this, requests doesn't handle it properly either.  My observations in this case are:
- the HTTPResponse._body attribute is correctly set
- Response.content returns None

If I recall, Response tries to re-use HTTPResponse._fp, but the file-like object's contents have already been read upon initialization of the HTTPResponse and therefore no longer exist.

On a second look, the additional call to read() happens within HTTPResponse as a result of the call to HHTPResponse.stream().  This is obviously a separate issue, but I guess the root issue here is that I can't seem to find a way to use the requests.Response object in a standalone fashion.


Do you mind taking a look at betamax (linked above) to see if that provides you some useful guidance?


Hint: `StringIO` is fundamentally wrong to be used as the fileobject for an `HTTPResponse` since the response will always be returning bytes. 


Can you make a specific suggestion?  I'd be happy to try it.  I will check
out betamax but haven't had a chance to do so yet.
Edit: I see that betamax uses io.BytesIO -- I tried this with the same result as StringIO.

On Thu, Jun 11, 2015 at 7:59 AM, Ian Cordasco notifications@github.com
wrote:

> Hint: StringIO is fundamentally wrong to be used as the fileobject for an
> HTTPResponse since the response will always be returning bytes.
> 
> —
> Reply to this email directly or view it on GitHub
> https://github.com/kennethreitz/requests/issues/2635#issuecomment-111164193
> .


Ok, so I checked out betamax and it looks like what you're doing is setting preload_content=False to avoid the initial read on the file-like body.  I guess that makes sense since an HTTPResponse is a file-like object, but is there a way to allow multiple sequential reads of Response.content?


If the `Response` object is from requests and is unaltered, it will cache the content so sequential accesses of the same response's content attribute should not be a problem. Unless I'm misunderstanding what you're asking.


That works, thanks!