[Python-ideas] Repurpose `assert' into a general-purpose check

Steven D'Aprano steve at pearwood.info
Tue Nov 28 00:41:35 EST 2017


On Tue, Nov 28, 2017 at 05:12:36AM +0300, Ivan Pozdeev via Python-ideas wrote:
> The `assert' statment was created the same as in previous languages like 
> C/C++: a check to only do in debug mode, when you can't yet trust your 
> code to manage and pass around internal data correctly.

That's not the sole use for assertions. Assertions are useful as checked 
comments, as "this can't happen" checks, as checks on your algorithm 
logic, as a poor man's form of design by contract, and more.


> Unlike C, Python does the aforementioned checks all the time, i.e. it's 
> effectively always in "debug mode".

Apart from -O which disables assertions. But in any case, the best use 
of assertions is not checking things which the interpreter is going to 
do anyway, but checking things which the interpreter can not and does 
not check automatically: your program logic. There is no way that the 
Python interpreter is going to do this check automatically, unless I 
write the assertion:

assert 0 <= r < abs(y)

That is copied straight out of one of my functions.

The point is, if you are only using assertions to check for things which 
the interpreter already does, you're not making good use of assertions.


> Furthermore, validation checks are an extremily common use case.
> I have been using assert in my in-house code for input validation for a 
> long time, 

I maintain that using assert for input validation for public functions 
(even if "public" in this case remains in-house) is certainly an abuse 
of assert, and STRONGLY oppose any change that supports that bad habit. 
Its okay to use asserts to validate input to *private* functions and 
methods (although even that is a slight code smell) but not public 
functions.


> So, I'm hereby proposing to:
> 
> * make `assert' stay in optimized mode
> * change its syntax to raise other types of exceptions

Very strong -1 on this. We already have syntax for raising other sorts 
of exceptions: raise.

if condition: raise Exception(message)

is the right way to spell 

assert not condition, Exception, message

The two require virtually the same amount of typing, so you don't even 
save any effort by using assert with an alternate exception type.

Leave assert for assertions. It is a *good* thing that assertions are 
visually distinct from input error checking. As things stand now, assert 
is a clear signal to the reader that this is an internal check which may 
be disabled safely.



-- 
Steve


More information about the Python-ideas mailing list