I love assert

Steven D'Aprano steve+comp.lang.python at pearwood.info
Mon Nov 17 03:09:13 CET 2014


Ethan Furman wrote:

> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
> 
> On 11/14/2014 06:58 PM, Steven D'Aprano wrote:
>> Ethan Furman wrote:
>>> 
>>> My point being:  a safety net that is so easily disabled does not count
>>> (IMHO) as a backup.
>> 
>> Assertions are not a backup or a safety net. [...]
> 
> Would you be happier if I phrased that as: Defensive programming
> techniques that can be unknowingly disabled by the end-user aren't very
> helpful?

No.

You appear to be labouring under the misapprehension that assertion-based
techniques (such as design by contract) are a technique for guarding
against expected errors in (say) data. If that were the case, then allowing
the end-user to disable such guards would be a bad idea. And that is one
reason (but not the only reason) why we should never use assert for "lazy
man's argument checking" of public library functions, or for validating
data.

# this is bad
positive_value = int(raw_input("Enter a positive integer: "))
assert positive_value > 0
blow_something_up_if_negative(positive_value)


But this is a misuse of assertions. If (generic) you is writing code like
that, PLEASE STOP, you're writing buggy code and giving assert a bad name.

Assertions should never be used to *enforce* correct behaviour. Assertions
are used for *verifying* correctness of the code, and they are a form of
runtime testing. The motto of Design By Contract might be "Trust, but
Verify".

Assertions are tests, not production code. They just happen to live inside
the production code, where they provide the additional benefits of checked
comments, validation of internal logic, and so on.

Since assertions are tests, the end-user should never, ever see an
AssertionError. If they do, it is a bug in your code. Since the end-user
will never see a failed assertion then it is harmless if they disable them.
At best it won't matter one whit, since your code is perfectly bug free[1].
At worst, they are no worse off than if you had neglected to write any
assertions at all.

But if they do run with assertions enabled, and one fails, then you, the
developer, get the bonus of "fail early, fail hard". Instead of the
undefined behaviour of buggy code, you get a nice clean assertion error
telling you what went wrong and where.



[1] Also on time and below budget.

-- 
Steven




More information about the Python-list mailing list