Skip to main content

This project was created with minimal help from AI assistants, mainly for the tests and a couple helper functions. This document is 100% human written.

Codelexity

version coverage python

A python package that helps you measure, visualize and ultimately manage code complexity.

Motivation

In the age of AI, codebases are becoming messier and more difficult to maintain. Codelexity helps you visualize and manage this complexity.

Quick Start

  • Step 1: uv add codelexity
  • Step 2: uv run codelexity <your_package_path> --plot - this will create a codelexity.html that you can open and play with in your browser.

Codelexity Graph Codelexity HTML report on the codelexity repo

Intuition

There's a ton of literature describing the relationship between complexity and maintainability of code.

The basics

Halstead measures are pretty robust in measuring the complexity. All Halstead metrics are derived from 4 numbers:

  1. $n_1$ = the number of distinct operators
  2. $n_1$ = the number of distinct operands
  3. $N_2$ = the total number of operators
  4. $N_2$ = the total number of operands

From these, another 7 metrics can be calculated, with most important the volume:

$$V=N*log_2(n)$$

where:

  • $n = n_1 + n_2$ the vocabulary of the program and
  • $N = N_1 + N_2$ the length of the program

Another important metric is the Mc Cabe Cyclomatic Complexity measured as:

$$M=E-N+2P$$

where $M$ the complexity, $E$ and $N$ the number of edges and nodes in the computation graph and $P$ the number of connected components.

With Halstead's volume and McCabe's complexity one can compute the Maintainability Index computed as:

$$ 171 - 5.2 * log_2(V) - 0.23 * M- 16.2 * log_2(SLOC)+ 50 * \sqrt{2.4 * perCOM}$$

where $SLOC$ the total lines of code and $perCOM$ the % of comments in the code.

Research is divided about how to interpret the score, with most academic sources (i.e. Ardito et al., 2020, Heričko & Šumak, 2023) citing $MI>=85$ as high, $85>MI>=65$ as medium and $MI<65$ as low and Microsoft Visual Studio citing $MI>=20$ as high, $20>MI>=10$ as medium and $MI<10$ as low.

This is how the metrics in this repo are calculated.

Maintainability propagation in the package graph

It is easy to understand that a densly connected dependency graph affects the maintainability. Central nodes (those that are imported from other modules that are reachable downstream) are more likely to cause issues. Therefore central modules that are not easy to maintain affect the maintainability of the whole package.

To measure centrality, codelexity uses Katz centrality. The centrality value is then multiplied by the module length and normalized by the sum of the respective value in all modules. The corresponding value is used as a weight to compute the total Maintainability Index.

Example - NetworkX

This is a result for the networkx library, a large and complex repo. The command used to create the analysis was:

codelexity networkx --json --plot

Codelexity on NetworkX

Note that the flags json and plot denote whether the output will be stored as a json named codelexity.json and as an html codelexity.html in the working directory.

The codelexity.json containts aggregate analytics for the whole package and per-module details.

{
    "analytics": {
        "total_lines": 234629,
        "total_functions": 9555,
        "total_modules": 624
    },
    "modules": {
        "conftest.py": {
            "imports": [
                "<stdlib>/importlib/metadata/__init__.py",
                "<stdlib>/os.py",
                "<stdlib>/warnings.py",
                "__init__.py"
            ],
            "total_lines": 262,
            "empty_lines": 39,
            "comments": 12,
            "code_length": 211,
...
        }

Running the tests

The suite lives in tests/ and uses the standard library's unittest — no test dependencies to install.

uv run python -m unittest discover        # all tests
uv run python -m unittest discover -v     # verbose, one line per test

Coverage, which needs no dev dependency either:

uv run --with coverage coverage run --source=src -m unittest discover
uv run --with coverage coverage report

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

codelexity-0.2.2.tar.gz (9.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

codelexity-0.2.2-py3-none-any.whl (11.6 kB view details)

Uploaded Python 3

File details

Details for the file codelexity-0.2.2.tar.gz.

File metadata

  • Download URL: codelexity-0.2.2.tar.gz
  • Upload date:
  • Size: 9.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for codelexity-0.2.2.tar.gz
Algorithm Hash digest
SHA256 2be075b859a9a9eda2ea8d615fa00fd0db58b42d8980c762c3b741eacef4b544
MD5 4c90b530629a0cdc263dcc555913294c
BLAKE2b-256 e4ebb7f809f67c7077e9a6ef27a5629c1e850c6461c5bca0654fb08dfc9e6a47

See more details on using hashes here.

File details

Details for the file codelexity-0.2.2-py3-none-any.whl.

File metadata

  • Download URL: codelexity-0.2.2-py3-none-any.whl
  • Upload date:
  • Size: 11.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for codelexity-0.2.2-py3-none-any.whl
Algorithm Hash digest
SHA256 96f3969e2099482cccc50931f2047e8160d63897217f1c2e9ebb4d8f7750acf7
MD5 f1f0496d99fb7b5e03460af8274e6d77
BLAKE2b-256 32da2cd6d3e94274df811f2e2a5a7cb0dd959c2d6846997d9c803dc18c8154a5

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page