DekGenius.com
[ Team LiB ] Previous Section Next Section

24.6 The assert Statement

As a somewhat special case, Python includes the assert statement. It is mostly syntactic shorthand for a common raise usage pattern, and can be thought of as a conditional raise statement. A statement of the form:

assert <test>, <data>          # The <data> part is optional.

works like the following code:

if __debug__:
    if not <test>:
        raise AssertionError, <data>

In other words, if the test evaluates to false, Python raises an exception, with the data item as the exception's extra data (if provided). Like all exceptions, the assertion error exception raised will kill your program if not caught with a try.

As an added feature, assert statements may also be removed from the compiled program's byte code if the -O Python command-line flag is used, thereby optimizing the program. AssertionError is a built-in exception, and the __debug__ flag is a built-in name that is automatically set to 1 (true) unless the -O flag is used.

24.6.1 Example: Trapping Constraints (but Not Errors)

Assertions are typically used to verify program conditions during development. When displayed, their error message text automatically includes source code line information, and the value you listed in the assert statement. Consider asserter.py:

def f(x):
    assert x < 0, 'x must be negative'
    return x ** 2

% python
>>> import asserter
>>> asserter.f(1)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "asserter.py", line 2, in f
    assert x < 0, 'x must be negative'
AssertionError: x must be negative

It's important to keep in mind that assert is mostly intended for trapping user-defined constraints, not for catching genuine programming errors. Because Python traps programming errors itself, there is usually no need to code asserts to catch things like out-of-bounds indexes, type mismatches, and zero divides:

def reciprocal(x):
    assert x != 0     # a useless assert!
    return 1 / x      # python checks for zero automatically

Such asserts are generally superfluous. Because Python raises exceptions on errors automatically, you might as well let Python do the job for you.[5] For another example of assert common usage, see the abstract superclass example of Chapter 21; there, we used assert to make calls to undefined methods fail with a message.

[5] In most cases, at least. As suggested in Part IV, if a function has to perform long-running or unrecoverable actions before it reaches the place where an exception will be triggered, you still might want to test for errors. Even in this case, though, be careful not to make your tests overly specific or restrictive, or you will limit your code's utility.

    [ Team LiB ] Previous Section Next Section