Say “no” to import side‐effects in Python

When you write Python code, please don’t have side‐effects in your module imports.

I must be able to import your module—​any module—​at any time without anything breaking.

Here’s an example of the type of problem that import side‐effects causes, on my laptop which has accumulated almost five years of Things of Diverse Character:

>>> help('modules')
Please wait a moment while I gather a list of all available modules...

WARNING: Running on Linux, but cannot use Epoll Twisted reactor.
 => reactor already installed
Will let Twisted choose a default reactor (potential performance degradation).
WARNING:OpenGL.Tk:Expected Tk Togl installation in /usr/lib/python2.7/dist-packages/OpenGL/Tk/togl-linux2-64
/usr/lib/python2.7/dist-packages/gtk-2.0/gtk/ RuntimeWarning: PyOS_InputHook is not available for interactive use of PyGTK
[1]    9098 segmentation fault (core dumped)  python

The first time I ran it today, it took upwards of a minute before it got to the segfault. Immediately after, with a hot cache, it still took almost ten seconds to get there—​things are simply doing too much at import time.

gdb reveals, by the way, that the segfault is in, because /usr/lib/python2.7/dist-packages/frescobaldi_app/icons/ saw fit to call QIcon.themeSearchPaths() (with no QApplication set up, which Qt requires), something it flatly shouldn’t be doing at import time.

Python has tried to provide a useful feature in help('modules'), but other programmers have scuppered it by their laziness and lack of conformance to Best Practices™.

Last time I tried help('modules') I didn’t have Frescobaldi installed; at that time, some GUI tests of some form ran, so I had a handful of windows popping up about the place briefly. It still crashed somewhere later, can’t remember where.

… and it only got that far because I had already removed a piece of code (from rst2pdf, I think it was) which had tests which, were the environment not set up to its satisfaction (specifically, it wanted to be in its source repository—​the file was not supposed to have been installed) raised SystemExit.

You see, at that time I wanted to see if I could get help('modules') to work.

I gave up.