py-metrics

Metrics Reference

PyMetrics exports four CSV-ready tables: file, class, function, and summary. The UI uses the same metric dictionary as this page: every i icon in the dashboard opens the detailed reference view in a new tab and highlights the selected metric.

For the dataset release contract, see dataset/schema.json and dataset/DATA_DICTIONARY.md.

How to read metrics

Metrics are signals, not verdicts. A high value should usually answer “where should I look first?” rather than “this code is bad.” The most useful readings combine families:

File-Level Metrics

Group Columns Source What it helps with
Size / raw loc, sloc, lloc, cloc, blank, comments_ratio Radon raw Baseline scale, documentation density, normalization.
Cyclomatic complexity cc_mean, cc_max, cc_min, cc_sum, cc_rank, num_functions, num_classes, num_methods Radon CC Branching/test effort and risky functions/files.
Maintainability mi_score, mi_rank Radon MI High-level maintainability triage; higher is better.
Halstead h1, h2, n1, n2, vocabulary, length, calculated_length, volume, difficulty, effort, time, bugs_halstead Radon Halstead Cognitive-load and information-content signals.
Git history age_days, revisions, authors, avg_loc_added, avg_loc_deleted PyDriller Change pressure, ownership breadth, churn hotspots.
Pylint pylint_score, pylint_errors, pylint_warnings, pylint_conventions, pylint_refactors Pylint Lint quality, likely mistakes, style/refactor suggestions.
Imports imports_count, stdlib_imports, third_party_imports, internal_imports, fan_out Custom AST import classifier Dependency footprint and coupling surface.

Cyclomatic Complexity

Thomas McCabe introduced cyclomatic complexity in 1976 as a graph-theoretic count of independent paths through a program. In practice, cc rises when code adds branches: if, for, while, exception handlers, boolean decision points, and similar control-flow constructs.

Use it to estimate test effort and review risk. A single function with very high cc deserves attention even when file-level averages look fine.

References: McCabe 1976, Radon documentation.

Maintainability Index

Maintainability Index combines size, cyclomatic complexity, Halstead volume, and comment signal into a composite score. It is useful as a dashboard KPI because it compresses several dimensions into one number, but it should not replace the underlying metrics.

Use it as a triage entry point, then inspect cc_*, volume, loc, and comments to understand why a file scored poorly.

References: Maintainability Index overview, Radon documentation.

Halstead Software Science

Maurice Halstead proposed software-science measures in 1977. The model treats programs as operators and operands, then derives vocabulary, length, volume, difficulty, effort, time, and estimated bugs. PyMetrics keeps the full family because it is common in empirical software engineering datasets.

Column Meaning
h1, h2 Distinct operators and operands.
n1, n2 Total operator and operand occurrences.
vocabulary h1 + h2.
length n1 + n2.
calculated_length Theoretical program length from vocabulary.
volume Information content of the implementation.
difficulty Estimated difficulty from operator/operand diversity and reuse.
effort volume * difficulty, a relative cognitive-effort signal.
time Historical effort-to-time conversion.
bugs_halstead Formula-based bug estimate; not a real defect label.

Use Halstead metrics comparatively within the same toolchain. They are useful dataset features, but the historical time and bugs_halstead formulas should be treated as relative signals.

References: Halstead 1977, Radon documentation.

Class-Level CK Metrics

The Chidamber-Kemerer metric suite became a standard object-oriented metric family in the 1990s. PyMetrics adapts these metrics to Python with an AST walker and project-local class registry.

Column Meaning Typical use
wmc Weighted Methods per Class: sum of method complexity. Large or hard-to-test class detection.
dit Depth of Inheritance Tree. Hidden behavior / inheritance risk.
noc Number of immediate children. Base-class influence and change ripple.
cbo Coupling Between Objects: distinct project classes referenced. Coupling hotspots.
rfc Response For a Class: own methods plus invoked methods. Behavioral surface area.
lcom Lack of Cohesion of Methods. Split-class candidates.
nom, nof, nosf, nosm Method, instance-field, static-field, and static-method counts. Class shape and statefulness.
norm Number of overridden methods. Inheritance behavior review.
noc_methods Public method count. API surface.
loc_class Source span of the class definition. Class size context.

Reference: Chidamber & Kemerer 1994.

Git Process Metrics

Static code metrics describe what the code looks like now. Process metrics describe how turbulent it has been. PyMetrics populates these only when CLONE_SHALLOW=false, because shallow clones do not contain enough history.

Column Meaning
age_days Days since the file first appeared in history.
revisions Commits that touched the file.
authors Distinct author count, not exported identities.
avg_loc_added, avg_loc_deleted Average churn per file-touching commit.

Use these with structural metrics. A high-complexity file that changes often is usually more urgent than a high-complexity file that has been stable for years.

Reference: PyDriller documentation.

Pylint and Dependency Metrics

Pylint metrics capture lint quality and likely correctness/style issues. Dependency metrics come from Python’s AST and classify imports as standard library, third-party, or internal.

Column Meaning
pylint_score Pylint aggregate score from 0 to 10.
pylint_errors, pylint_warnings, pylint_conventions, pylint_refactors Pylint message counts by category.
imports_count Total imports discovered in a file.
stdlib_imports, third_party_imports, internal_imports Import classification.
fan_out Number of distinct imported modules.

Use lint and dependency metrics as context: high fan_out can mean orchestration code, integration code, or excessive coupling, and the difference matters.

References: Pylint documentation, Python ast module.

Summary Metrics

The summary endpoint and metrics_summary.csv provide repo-level aggregates:

Operational Trade-Offs