Anatomy of a Python Package

If all subsystems can communicate with all other subsystems, you lose the benefit of separating them at all. Make each subsystem meaningful by restricting communications.

Steve McConnell

Below is a tool for examining how modules in a Python package communicate with each other.

Module Graph

Each node in this graph is a module in the selected package. Edges indicate imports. Placing the mouse over a node selects that module and all of its dependencies.

Adjacency Matrix

This is another way to represent the graph above. In the adjacency matrix if cell (i, j) is black this means module i directly imports module j. If the cell is dark gray this means module i indirectly imports module j.

Propagation Cost

This value is the total number of direct and indirect dependencies in a project divided by the total number of modules. This is a measure of how difficult it can be to modify a module in this package.

The source code for this project is available on github. This project uses Python’s inspect module, flask, and d3, all of which are awesome. Thanks to Alan MacCormack for highlighting the usefulness of examining a package’s adjacency matrix and using propagation cost to measure modularity.