Clarity vs. code reuse/generality

Steven D'Aprano steven at REMOVE.THIS.cybersource.com.au
Thu Jul 9 22:57:44 EDT 2009


On Fri, 10 Jul 2009 03:28:04 +0100, Nobody wrote:

> On Thu, 09 Jul 2009 04:57:15 -0300, Gabriel Genellina wrote:
> 
>> Nobody says you shouldn't check your data. Only that "assert" is not
>> the right way to do that.
> 
> "assert" is not the right way to check your *inputs*. It's a perfectly
> reasonable way to check data which "should" be valid, as well as a way
> to document what variables are supposed to contain.

Where are those variables coming from?

The distinction really boils down to this:

* asserts should never fail. If there is any chance that an assertion 
might fail outside of test suites, then don't use assert.


You can't control what input the caller provides to a function, so unless 
the data is generated inside the function, a caller might provide 
something unexpected. Therefore, assert is inappropriate for checking 
function parameters, even if that function is "private" and only called 
by your own functions.

(1) So-called "private" or "internal" functions have a habit of becoming 
public, and then you have asserts in public functions.

(2) If public() calls _private(x), and _private uses assert to check the 
value of x, there is a risk that if public() is buggy and supplies an 
invalid x, the assertion will never be checked and _private() will return 
incorrect results.

(3) assert is absolutely unsuitable for enforcing pre-conditions and post-
conditions, unless such conditions are mere "guidelines", because assert 
can be switched off at runtime.



It's a fine line to draw. Obviously, if we think something *truly* can 
never fail, we don't bother checking it:

def add(x, y):
    result = x+y
    assert result-y == x
    assert result-x == y
    return result

is probably overkill for most programs, and yet surprisingly those 
assertions will commonly fail for float arguments!




-- 
Steven



More information about the Python-list mailing list