Amazon.com Widgets Don’t put parentheses around your assert expressions and the error string! | t+1: Matt Wilson's blog

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 "<ipython console>", line 1, in <module>
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 "<ipython console>", line 1
     (assert 1 == 0, "OH NOES")
           ^
SyntaxError: invalid syntax
 
>>> assert 1 == 0,
------------------------------------------------------------
   File "<ipython console>", line 1
     assert 1 == 0,
                   ^
SyntaxError: invalid syntax
 

Dangit.

9 Comments »

  1. ulrik said,

    December 18, 2007 @ 7:40 pm

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

  2. Daniel said,

    December 18, 2007 @ 8:25 pm

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

  3. Justin said,

    December 18, 2007 @ 8:34 pm

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

  4. sri said,

    December 18, 2007 @ 9:24 pm

    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.

  5. Ycros said,

    December 18, 2007 @ 9:56 pm

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

  6. anonymous said,

    December 18, 2007 @ 10:13 pm

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

    /home/osuchwa/ in ()

    : OH NOES

    In [2]:

  7. David Goodger said,

    December 18, 2007 @ 11:53 pm

    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.

  8. Christian Wyglendowski said,

    December 19, 2007 @ 12:07 am

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

    py.test FTW :-)

  9. matt said,

    December 19, 2007 @ 12:12 pm

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

RSS feed for comments on this post · TrackBack URI

Leave a Comment