Don’t put parentheses around your assert expressions and the error string!

I had a bunch of unit tests that were passing even though I knew they should be failing. I traced it down to the fact that I put parentheses around my assert statements because the tests were really really long and I wanted to put the error string on a separate line.

This is what I spent the last 45 minutes trying to figure out:

>>> assert 1 == 0, "OH NOES"
------------------------------------------------------------
Traceback (most recent call last):
File "", line 1, in
AssertionError: OH NOES

>>> assert (1 == 0,
... "OH NOES")

>>> assert (1 == 0, "OH NOES")

>>>

The assertion doesn’t raise because I suspect that the assert evaluates each element in the tuple separately, and the string returns True.

And these don’t work, but for different reasons:

>>> (assert 1 == 0, "OH NOES")
------------------------------------------------------------
File "", line 1
(assert 1 == 0, "OH NOES")
^
SyntaxError: invalid syntax

>>> assert 1 == 0,
------------------------------------------------------------
File "", line 1
assert 1 == 0,
^
SyntaxError: invalid syntax

Dangit.

  • A non-empty tuple (or any container) is always true!

  • Daniel

    Actually, “assert (False, False)” also doesn’t raise, so it’s an “assert bool(X)# for any X that is True” kind of issue 🙂

  • Justin

    you can still use a backslash at the end of the line to split it up

  • sri

    assert (1==0, “OH NOES”) doesn’t work because
    (1==0, “OH NOES”) is a tuple containing 2-elements,
    which after evaluation is (False, “OH NOES”).

    a non-empty tuple evaluates to True in python.

  • For unit tests I much prefer using TestCase’s assertEqual and assert_ methods.

  • anonymous

    In [1]: assert 1==0, \
    …: “OH NOES”
    —————————————————————————
    Traceback (most recent call last)

    /home/osuchwa/ in ()

    : OH NOES

    In [2]:

  • Just relocate the open parenthesis:

    assert some_condition, (
    very_long_string_expression)

    If the condition is long:

    assert (a_very_long
    condition_expression), (
    very_long_string_expression)

    Just make sure the first close paren is on the same line as the second open paren.

  • Yeah, like Justin and anonymous said, the trailing backslash works well for putting the error message on the following line.

    py.test FTW 🙂

  • I am very grateful for all the feedback I got on this post. Thanks everyone!