When to use assert
steve+comp.lang.python at pearwood.info
Wed Oct 22 17:49:31 CEST 2014
Chris Angelico wrote:
> On Wed, Oct 22, 2014 at 12:44 PM, Steven D'Aprano
> <steve+comp.lang.python at pearwood.info> wrote:
>> def do_something(instance_or_id):
>> instance = Model.get(instance_or_id)
>> assert isinstance(instance, Model)
>> # Code that assumes that instance is an object of type Model
>> That means that the logic for what is acceptable as a Model is all in one
>> place, namely the Model.get method, and callers don't need to care about
>> the pre-condition "argument is a Model or an integer ID", they only need
>> to care about the post-condition "result of get() is a Model".
> And at that point, the assertion is redundant, on par with:
> a = len(seq)
> assert isinstance(a, int)
> because you shouldn't have to assert what's part of a function's
That depends on how well you trust the function, how paranoid you are, and
whether you wish to include a checked comment, among other considerations.
I'd prefer to write the above than:
a = len(seq)
# At this point, a is an int.
because comments inside code that aren't checked are technically known
as "lies" <http://import-that.dreamwidth.org/956.html>. Ha ha only serious.
I wouldn't write such a comment for len() since I would expect anyone
reading the code to know what len() does, but the same doesn't necessarily
apply for every function call I make.
Checking the post-condition of a built-in like len() is too paranoid for my
tastes, as len() enforces the rule that __len__() methods return a
non-negative integer, and there are millions of lines of Python code around
the world calling len(). Somebody surely have noticed by now if len()
violated that post-condition. But for a function from my own code base,
where I might only have dozens of users (oh to have that many!) and fewer
unit tests than perhaps I ought to, I might not be quite so confident that
the assertion was redundant. To err is human, and so there are occasions
when it is appropriate to trust but verify.
As I wrote:
This is why assert can be divisive. Since we can vary in our
confidence about the correctness of code, one person's useful
assertion may be another person's useless runtime test.
More information about the Python-list