Quantcast
Viewing latest article 3
Browse Latest Browse All 17

Answer by Tomasz Gandor for Best practice for using assert?

Well, this is an open question, and I have two aspects that I want to touch on: when to add assertions and how to write the error messages.

Purpose

To explain it to a beginner - assertions are statements which can raise errors, but you won't be catching them. And they normally should not be raised, but in real life they sometimes do get raised anyway. And this is a serious situation, which the code cannot recover from, what we call a 'fatal error'.

Next, it's for 'debugging purposes', which, while correct, sounds very dismissive. I like the 'declaring invariants, which should never be violated' formulation better, although it works differently on different beginners... Some 'just get it', and others either don't find any use for it, or replace normal exceptions, or even control flow with it.

Style

In Python, assert is a statement, not a function! (remember assert(False, 'is true') will not raise. But, having that out of the way:

When, and how, to write the optional 'error message'?

This acually applies to unit testing frameworks, which often have many dedicated methods to do assertions (assertTrue(condition), assertFalse(condition), assertEqual(actual, expected) etc.). They often also provide a way to comment on the assertion.

In throw-away code you could do without the error messages.

In some cases, there is nothing to add to the assertion:

def dump(something): assert isinstance(something, Dumpable) # ...

But apart from that, a message is useful for communication with other programmers (which are sometimes interactive users of your code, e.g. in Ipython/Jupyter etc.).

Give them information, not just leak internal implementation details.

instead of:

assert meaningless_identifier <= MAGIC_NUMBER_XXX, 'meaningless_identifier is greater than MAGIC_NUMBER_XXX!!!'

write:

assert meaningless_identifier > MAGIC_NUMBER_XXX, 'reactor temperature above critical threshold'

or maybe even:

assert meaningless_identifier > MAGIC_NUMBER_XXX, f'reactor temperature({meaningless_identifier }) above critical threshold ({MAGIC_NUMBER_XXX})'

I know, I know - this is not a case for a static assertion, but I want to point to the informational value of the message.

Negative or positive message?

This may be conroversial, but it hurts me to read things like:

assert a == b, 'a is not equal to b'
  • these are two contradictory things written next to eachother. So whenever I have an influence on the codebase, I push for specifying what we want, by using extra verbs like 'must' and 'should', and not to say what we don't want.

    assert a == b, 'a must be equal to b'

Then, getting AssertionError: a must be equal to b is also readable, and the statement looks logical in code. Also, you can get something out of it without reading the traceback (which can sometimes not even be available).


Viewing latest article 3
Browse Latest Browse All 17

Trending Articles