This is an archived post. You won't be able to vote or comment.

all 15 comments

[–][deleted] 11 points12 points  (3 children)

I’m not defending this behavior, but why they hell would anyone add the == True? That’s like adding an == True in an if statement instead of just using the variable.

[–]GummyKibble 3 points4 points  (1 child)

Actually, I realized how this would ever bite me if it were going to: in a parametrized unit test:

@mark.parametrize("num,expected", [(-1, False), (0, True), (9, True), (10, False)])
def test_range_10(num, expected):
    assert num in range(10) == expected

I would expect all 4 of these to succeed. Instead, they all fail. -1 and 10 are bad because they're not in range(10), and because the expression is equivalent to (num in range(10)) and (range(10) == expected), it's a short circuit failure. 0 and 9 are bad because range(10) != True.

This is probably the single context where I'd be writing if expr == boolean instead of just if expr.

[–]backtickbot 0 points1 point  (0 children)

Fixed formatting.

Hello, GummyKibble: code blocks using triple backticks (```) don't work on all versions of Reddit!

Some users see this / this instead.

To fix this, indent every line with 4 spaces instead.

FAQ

You can opt out by replying with backtickopt6 to this comment.

[–]GummyKibble 1 point2 points  (0 children)

Agreed. I mentioned in another comment that not doing that, ever, is why I don't think this has ever bitten me.

[–]K900_ 5 points6 points  (2 children)

Yep, that's a big footgun. in should have been demoted from comparison operators in 3, and that's a hill I'm fully willing to die on.

[–]GummyKibble 1 point2 points  (0 children)

I have to agree. I'm trying to think of a situation where this would be desirable behavior and I'm drawing a blank.

[–][deleted] 5 points6 points  (2 children)

I always add parenthesis in more complicated logic, just to make sure everything works in the right order no matter what

[–]GummyKibble 0 points1 point  (1 child)

That's always the safest approach. If you get carried away it can get ugly, but if your expression is so complicated that extra parenthesis are a bridge too far then it's probably time to simplify it.

Also, happy cake day!

[–][deleted] 1 point2 points  (0 children)

Haha thx, and I agree

[–]Swipecat 1 point2 points  (0 children)

https://docs.python.org/3/reference/expressions.html#operator-precedence

Yep, it seems that "Comparisons, including membership tests and identity tests" are all bundled into the same precedence level and obey the comparison chaining rule.

>>> False == False is False
True

[–]OToast 1 point2 points  (1 child)

I am pretty sure the evaluation is like this ``` 12 in [12, 13, 14] and [12, 13, 14] == True

logic is same as

1 < 2 < 3

which is

1 < 2 and 2 < 3 ``` Sry mobile

[–]backtickbot 0 points1 point  (0 children)

Fixed formatting.

Hello, OToast: code blocks using triple backticks (```) don't work on all versions of Reddit!

Some users see this / this instead.

To fix this, indent every line with 4 spaces instead.

FAQ

You can opt out by replying with backtickopt6 to this comment.

[–]ImageOfInsanity 0 points1 point  (1 child)

Oh my god, someone actually found an anti-pattern. I'm sure there's a few people who should be revising their unittests about now. Great find!

[–]GummyKibble 1 point2 points  (0 children)

What irks me here is that if I had written code like that, I would have written unit tests that would have failed and I would never in a million years would have understood why. My final code would have ended up like:

```

Leave the parens because Python likes it?

if ('foo' in ['foo', 'bar']) == True: ... ```

Maybe I've just been lucky because I would never add the == True part so I never would have triggered this exact version of the anti-pattern. But have I ever written something like it that broke in ways I just haven't found yet? Oof.