Chapter 5. Surprises

If you do not expect the unexpected you will not find it, for it is not to be reached by search or trail.

Heraclitus

At last, we get to the really weird stuff, the things that go bump in the night and cause someone to get paged to solve them. These are some of the many ways that you can create little time bombs in your code, just waiting to surprise and delight you at some point in the future.

Importing Everything

PEP-8 recommends avoiding wildcard imports (from some_module import *), and it’s absolutely right. One of the most exciting reasons is that it opens your code up to some interesting ways to break in a multideveloper environment.

Suppose there’s some module foo.py that has a bunch of great things in it, and your code wants to make use of many of them. To save yourself the tedium of either importing lots of individual names, or importing just the module and having to type its name over and over again, you decide to import everything:

import time
from foo import *


def some_function(...):
    current_time = time.time()
    ...

This works fine, your tests pass, you commit the change, and off it goes up the deployment pipeline. Time passes, until one day errors start flooding in. The traceback tells you that your code is causing AttributeError exceptions when trying to call time.time(). But the unit tests are all green—not only are the tests for your code passing, so are the tests for foo.

What’s happening in this ripped-from-reality scenario is that someone ...

Get How to Make Mistakes in Python now with the O’Reilly learning platform.

O’Reilly members experience live online training, plus books, videos, and digital content from nearly 200 publishers.