Wily¶
The Zen of Python [1] emphasises complexity reduction in many ways:
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Wily is a command line tool for checking the complexity of Python code in tests and applications. For this purpose, Wily uses the following metrics:
- Cyclomatic complexity
measures the complexity of code by the number of linearly independent paths in the control flow graph.
The Software Engineering Institute at Carnegie Mellon University distinguishes the following four levels of risk [2]:
Cyclomatic complexity
Risk assessment
1–10
Simple programme without much risk
11–20
moderate risk
21–50
complex, high-risk programme
> 50
untestable programme with very high risk
- Halstead complexity measures
Statically analysing procedure that calculates the difficulty of the programme, the effort and the implementation time from the number of operators and operands.
- Maintainability Index
is based on the cyclomatic complexity, the Halstead complexity measures and the number of lines of code [3]:
Index
Maintainability
0–25
unmaintainable
25–50
worrying
50–75
in need of improvement
75–100
Superhero code
See also
Installation¶
Wily can be easily installed with
$ uv add wily
You can then check the installation with
$ uv run wily --help
Usage: wily [OPTIONS] COMMAND [ARGS]...
Version: 1.19.0
🦊 Inspect and search through the complexity of your source code. To get
started, run setup:
$ wily setup …
Configuration¶
A wily.cfg
file can be created in the project directory with the list of
available operators:
[wily]
# list of operators, choose from cyclomatic, maintainability, mccabe and raw
operators = cyclomatic,raw
# archiver to use, defaults to git
archiver = git
# path to analyse, defaults to .
path = /path/to/target
# max revisions to archive, defaults to 50
max_revisions = 20
Python code in .ipynb
files is also usually recognised automatically.
However, you may be able to disable this for a Jupyter notebook with
ipynb_support = false
or for individual cells with
ipynb_cells = false
Use¶
… as a command line tool¶
Building a cache with the statistics of the project
Note
Wily assumes that your project folder is a Git repository. However, Wily does not create a cache if the working directory is dirty.
$ uv run wily build
Show metric
$ uv run wily report
This outputs both the metric and the delta to the previous revision.
Show ranking
$ uv run wily rank
This shows the ranking of all files in a directory or a single file based on the specified metric, if present in
.wily/
.Show graph
$ uv run wily graph
This displays a graph in the default browser.
Show build directory information
$ uv run wily index
List the metrics available in the Wily operators
$ uv run wily list-metrics
… as pre-commit hook¶
You can also use Wily as a pre-commit framework. To do this, you would
have to add the following to the pre-commit-config.yaml
configuration file, for example:
repos:
- repo: local
hooks:
- id: wily
name: wily
entry: wily diff
verbose: true
language: python
additional_dependencies: [wily]
… in a CI/CD pipeline¶
Usually Wily compares the complexity with the previous revision. However, you
can also specify other references, for example HEAD^1
with
$ uv run wily build src/
$ uv run wily diff src/ -r HEAD^1