Abort early or crash late
Last week I was discussing with a colleague a problem I had with Python's assert statement, that can't be disabled. Let's consider this code snippet that sums up the situation*:
# expects digit as an integer, # unfrequentFlag as a boolean def fct(digit, unfrequentFlag=False): assert type(digit) is int print("you gave digit #{}".format(digit)) if unfrequentFlag: digit += 1 return digit # test cases fct(1) fct("2") fct("3", unfrequentFlag=True)
From the bug taxonomy presented earlier, we can say that:
- case #2 and #3 are code defects that infect the program state,
- program instruction digit += 1 causes the failure if the state is infected *if the unfrequentFlag is set,
- assertion type(digit) is int ensures that the state is correct when entering the function body.
In Python, asserts can't be disabled, and that's a problem for me, because I wanted to have the ability:
- during development, to abort early, that is, as soon as I know the program state is infected
- in production, to avoid crashes as much as possible.
In case #2, the execution won't crash (without the assert I mean). The state is invalid, but the instruction causing the failure is not executed, so it goes unnoticed, everybody's happy!
Is this reasonment flawed? Did I miss something in duck typing? I guess so, otherwise assertion could be disabled more easily in Python ...
In statically typed languages like Java, such problems are detected even earlier, by the type system of the compilier, but that's not the discussion here! Java also faces that problem I descibed here, for instance with a null object, as assert(obj != null) and later the dereference of the object in question.
I also know that unit testing is the solution, but who writes unit tests for a code that is in no way critical? (I had to write non-regression tests for the patches I contributed to GDB, and along with documentation it can be longer to write than the patch itself, so you must have good motivations to slow down the development by a factor of two! Automatic tools like the compiler parser gives you the first level of guarantee for free!
* I know this is not pythonic code, that's just an example ;-)