Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can you have too many asserts (in Python)?

Lately, I've been adding asserts to nearly every single function I make to validate every input as sort of a poor-man's replacement for type checking or to prevent myself from accidentally inputting malformed data while developing. For example,

def register_symbol(self, symbol, func, keypress=None):
    assert(isinstance(symbol, basestring))
    assert(len(symbol) == 1)
    assert(callable(func))
    assert(keypress is None or type(keypress) is int)
    self.symbols_map[symbol] = (func, keypress)
    return

However, I'm worried that this goes against the idea of duck typing, and that I might be going too overboard or constricting myself unnecessarily. Can you ever have too many assert statements? When's a good time to stop?

like image 283
Michael0x2a Avatar asked Mar 08 '12 20:03

Michael0x2a


People also ask

Is it good to use assert Python?

Python's assert statement is a debugging aid, not a mechanism for handling run-time errors. The goal of using assertions is to let developers find the likely root cause of a bug more quickly. An assertion error should never be raised unless there's a bug in your program.

What happens when Python assert fails?

If an assertion fails, then your program should crash because a condition that was supposed to be true became false. You shouldn't change this intended behavior by catching the exception with a try … except block. A proper use of assertions is to inform developers about unrecoverable errors in a program.

How do you assert multiple conditions in Python?

Python Assert Multiple Lines. If you want your assertion message to expand to multiple lines: Wrap the message around a set of parentheses. Break the lines as desired.

How do you use asserts in Python?

Syntax for using Assert in Pyhton: In Python we can use assert statement in two ways as mentioned above. assert statement has a condition and if the condition is not satisfied the program will stop and give AssertionError . assert statement can also have a condition and a optional error message.


1 Answers

I only use asserts if they provide far better diagnostics than the error messages that I would get otherwise. Your third assert

assert(callable(func))

might be an example for such an assert -- if func is not callable, you will get an error message at a completely different line of code than where the actual error is, and it might not be obvious how the non-callable object ended up in self.symbols_map. I write "might" because this depends on the rest of your code -- if this is the only place where self.symbols_map gets updated, the assert might also be unnecessary.

The first and last assert definitely are against the idea of duck-typing, and the second one is redundant. If symbol isn't a string of length 1, chances are that self.symbols_map[symbol] will raise a KeyError anyway, so no need for the asserts.

The last assert is also wrong -- type(keypress) cannot be None, and type checks should be done with isinstance(). There might be very specialised applications where you cannot allow subtypes, but than the check should be performed with type(x) is int instead of type(x) == int. Checking for None should be done by x is None, not by type(x) is NoneType.

You should probably write a good set of unit tests -- they will be far more useful than the asserts, and might make almost all of your asserts redundant.

like image 124
Sven Marnach Avatar answered Oct 05 '22 23:10

Sven Marnach