bool(failure response) is False

This is rather surprising, and not documented that I've seen (though I could certainly have missed it):

```
>>> r = requests.request('get', 'http://google.com/aopsdufsaf')
>>> r
<Response [404]>
>>> bool(r)
False
```

To me, "failure = false" is neither intuitive nor expected.


+1

A common pattern is

``` python
resp = None

try:
    resp = requests.get(...)
except:
    log.exception("ruh roh")

if resp:
    print("we got somethin'!")
    handle_resp(resp)
```

The current implementation of `__bool__` makes this intuitive pattern very tricky when writing code that accounts for erroneous status codes.


Hey @slinkp thanks for opening this!

In this case, what you're looking for is an explicit attribute: `r.ok`

The fact of the matter is that this works on Python 3 because we define `__bool__`. If we define `__nonzero__` on Python 2 this would work there as well. That said, I think you should be using the `r.ok` pattern anyway. It's a far better pattern personally.

@jamesob you're getting exactly what you ask for in that case, sorry to say it. You did get something if `resp` is not `None`. If you want a "good" response that also isn't None, you should be explicit about it:

``` python
if resp and resp.ok:
    print("we got something!")
    handle_resp(resp)
```

Even if the `__nonzero__` bug is fixed, this is still far more obvious to anyone who is going to come along and read your code that you're not only expecting a non-`None` value but also a `2xx` response.


Wait never mind, we do implement `__nonzero__`. So `bool(resp)` should work just fine. Investigating.


@sigmavirus24 heh, appears this issue has just bitten you too. 

> You did get something if resp is not None.

isn't true given the current implementation of `__nonzero__` (which kicks to `ok`), which is the point I was trying to get across.


``` pycon
>>> import requests
r>>> r = requests.get('https://api.github.com/user')
>>> r
<Response [401]>
>>> bool(r)
False
>>> r = requests.get('http://madisonpl.us/rubby')
>>> r
<Response [404]>
>>> bool(r)
False
```

What version of requests are both of you on?


Oh, I misread the issue. >_< Yeah that's something I disagree with :). I bet it was someone else's feature request and not something we can "fix" until requests 3.


``` python
In [3]: r = requests.get('http://google.com/awefawefae')

In [4]: r
Out[4]: <Response [404]>

In [5]: if r:
   ...:     print "yo"
   ...:     

In [6]: requests.__version__
Out[6]: '2.1.0'
```


@jamesob yeah I asked that because I thought I read that `bool(resp) is True` in the original issue. I've had too much caffeine to deal with the sleep deprivation caused by PyCon. =D


haha, I hear ya. Anyways, would be awesome to get this ironed out.


Yeah I figured this would break backward compatibility... somebody somewhere is surely depending on the current behavior.  I just really dislike it :)

Thanks @sigmavirus24 


Yeah I'm :+1: for removing this. @Lukasa thoughts? 

I know it would have to wait for requests 3.0 but it might still be good to have a wishlist for 3.0 


I just chatted with Kenneth about this, he definitely doesn't like it. I think we should be leaving this on a wishlist for 3.0, but @kennethreitz might disagree.


I know Semantic Versioning isn't a hard rule but I really really really really would like it if it were =P


as the issue reporter, I would chime in to say semver++ ... don't break
things for people who rely on this behavior even if I hate it.

On Mon, Apr 14, 2014 at 5:56 PM, Ian Cordasco notifications@github.comwrote:

> I know Semantic Versioning isn't a hard rule but I really really really
> really would like it if it were =P
> 
> —
> Reply to this email directly or view it on GitHubhttps://github.com/kennethreitz/requests/issues/2002#issuecomment-40423225
> .

## 

http://www.slinkp.com


semver++ :)


I think this is an irrelevant design decision that should really never be relied on either way. In my opinion neither `__nonzero__` nor `__bool__` should have been implemented for response objects in the first place.

@jamesob In your first code snippet, you shouldn't be using None as a boolean anyways. Write `if resp is None:` instead and that pattern works fine. (Also, just FYI, `except:` should always be `except Exception:`, otherwise you catch things like KeyboardInterrupt which is baaaaaaad.)

The truthiness of an HTTP response is a very ambiguous concept. Instead, just use `response.ok` as was suggested earlier.

> Explicit is better than implicit.
> — Tim Peters


@fletom I'd like to remind you to [be cordial](http://www.kennethreitz.org/essays/be-cordial-or-be-on-your-way). The code snippets provided for this issue likely do no represent code actually copied and pasted from production code. They merely serve as examples to illustrate a point. There's no need to teach anyone about bad practices. All you needed to do was voice an opinion relevant to the discussion of what `bool(response)` would return.


@sigmavirus24 Sorry my comment came across as negative. I only meant to suggest a way that that common pattern can work with requests' current design. As KR suggested, the intention was to be educational/constructive and not insulting.


This was one of the earliest features of requests and should def be removed :)


Yep that's why it's lined up for 3.0 =D