Can someone explain WHEN to use and what are the BEST SUITABLE usage scenarios for assert?
My points are:
if not then raise
-O
it will be ignoredSo what are the usage scenarios for assert
in source code (not unit test)?
From my very traditional experiences, assert
should only exist in unit tests, really cannot get much point why it starts appearing in Python project code more and more.
A good way to think of an assert statement in library code is as a loaded comment, it's a like a little piece of documentation about how the code works (or how you thought it worked) that will blow up and make a big noise if the "comment" is ever making a claim that turns out to be wrong.
When you write an assert statement into source code (not test code), you should be very confident that it will not fire, regardless of the program input. Of course you can't be 100% certain that it will never fire, but you should be sure that if it were to fire then you have made an incorrect assumption somewhere and you'll need to revisit this section of the code.
Why add asserts into library code at all? If you should be sure they won't fire, then what's the point?
Don't use them to validate input! Use exceptions for that if necessary. If an assertion fires, that's a bug. If a user reports an unhandled AssertionError
, it is your problem and not the user's fault. Something needs to be fixed.
Here's an example of a bad assertion:
def square(n):
assert isinstance(n, int)
...
If this fires, that was the caller's fault. Should you need it, a TypeError
is more appropriate here than unhandled AssertionError
.
Here's an example of an ok assertion:
s = None
while s not in {'y', 'n'}:
s = input("do the thing? [y/n] ").lower()
if s == 'y':
# do the thing
else:
assert s == 'n'
# do other stuff
It doesn't validate data, i.e. the user can't type any input that would cause an assertion fire - the "assumption" the developer is making here is that since the while
loop has exited, s
must be 'y'
or 'n'
. This is better than an elif s == 'n':
, else: raise
type construction, because that else:
block could never be reached, so it would not receive test coverage unless you do some really intrusive mocking. Last but not least, it protects against entering the handling for the 'n'
branch incorrectly should the foolish future-you add 6 more choices to the prompt but only add handling for 5 of those choices (oops!)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With