In this particular situation, there was no else. I probably added an else clause with an assert return_value == False, as the function call was a virtual dispatch that could have many implementations. Of course, I wouldn't do that for every if/then/else statement in my code. In general, I'd prefer a stricter language that only permitted a boolean as a condition in the IF statement, avoiding this problem altogether.
If you are using truthy/falsey values, I think it can be a code smell that you are not doing enough to catch invalid values up front or should normalize the values closer to their creation point.
But the discussion is about truthy values and inexact comparisons - avoiding inexact comparisons and having an else means:
if something==True:
do_this()
elif something==False:
do_that()
else:
raise UserWarning("Shouldn't be here")
Which is a code smell to me. What I would do is:
assert isinstance(something, boolean), "Shouldn't happen"
do_this() if something else do_that()
(replace assert with something else if you want it not to be optimized away with -O; assert is a debug-only construct in Python. Or just drop the assert altogether. In most places, I would - there's no end to the amount of validation you could do, and most of it is unnecessary)
If you are using truthy/falsey values, I think it can be a code smell that you are not doing enough to catch invalid values up front or should normalize the values closer to their creation point.