CodeVariability for Python
CodeVariability compares UTF-8 source-code files and returns similarity matrices, descriptive statistics, representative rankings, and comparisons between independent groups. It helps you identify common structures and unusual variants in a collection without executing the submitted code.
Version 0.2.0 is the first release of this independent repository. The API is alpha. The distribution name is codevariability;
the import name and command are codevariability.
Installation
Python 3.10 or later is required. Install from PyPI:
python -m pip install codevariability==0.2.0
For development, install a checkout with python -m pip install ..
The historical 0.1.2 code is the implementation baseline; 0.2.0 is the first
public PyPI release. Use a new virtual environment when migrating from a
local historical installation.
Quick start
This example creates its own inputs and works with an installed package:
from pathlib import Path
from tempfile import TemporaryDirectory
from codevariability import analyze
with TemporaryDirectory() as directory:
folder = Path(directory)
(folder / "a.py").write_text("def total(a, b):\n return a + b\n", encoding="utf-8")
(folder / "b.py").write_text("def sum_values(x, y):\n return x + y\n", encoding="utf-8")
result = analyze(folder, metrics="all")
print(result.statistics)
print(result.ranking)
print(result.most_representative)
The runnable example also exports JSON, CSV, and Excel. For the bundled input files, the CLI is:
codevariability analyze examples/inputs --metrics all --output analysis-output
codevariability analyze examples/inputs --metrics cosine jaccard --output analysis-output/report.xlsx
Inputs and metrics
Pass a directory or a list of file paths to analyze(). Directory scans are
not recursive. File basenames must be unique. Files are decoded as UTF-8,
including an optional BOM. Use extensions="py" or a list of extensions to
filter a directory.
| Metric | What it compares |
|---|---|
cosine |
Word frequencies in the full document. |
jaccard |
Sets of words in the full document. |
lcs |
The longest common subsequence of code tokens. |
levenshtein |
Token sequences using unit edit costs. |
ast_tree_edit_similarity |
Ordered, normalized Python syntax trees. |
metrics="all" includes all applicable metrics. Python AST analysis requires
Python inputs; explicit selection on incompatible inputs raises AnalysisError.
Source files are read in full. For Markdown, token and AST metrics use the
identified fenced code blocks; textual metrics include the full document.
Results and export
AnalysisResult exposes matrices, statistics, representativeness,
ranking, rankings_by_metric, most_representative, and most_distinct.
Similarities range from 0 to 1. Statistics use each unique pair once. Rankings
average within each available dimension and then give dimensions equal weight.
Use result.export(directory, formats=("json", "csv")) for machine-readable
results and tables, or result.to_excel(path) for a workbook. Outputs include
metric identifiers, normalization and runtime versions, and input hashes.
Spreadsheet exports escape formula-like labels; JSON retains the original
labels. See input/output details.
compare_groups() supports two groups or a mapping of two or more groups,
file-label permutation tests, and Holm-adjusted p-values. Each group needs at
least two files and groups must not share physical files. A complete example
is in examples/groups.py.
Optional JavaScript integration
The Python library works without Node.js. To request structural JavaScript or
TypeScript analysis through compare_groups(..., include_ast=True), install
the independent codevariability-js
package and make its command available on PATH. Alternatively, import a
single-metric JSON with load_matrix_json() and attach it with with_metric().
The Python build and normal test suite require no JavaScript checkout.
Limits and errors
Scores describe text, tokens, or syntax; they do not establish functional equivalence, correctness, authorship, or copied-code percentages. AST normalization removes concrete names and literal values. Different sources can therefore have structural similarity 1.
Exact tree comparison can be expensive. The default max_ted_cells=2_000_000
limits tables for each non-identical AST pair; exceeding it raises an error,
without approximation. None removes the limit. It does not limit source
file size, the full pairwise matrix, or total CPU time. Use trusted output
directories and apply application-level resource limits for untrusted inputs.
Expected input and serialization errors raise AnalysisError. JavaScript
integration also supports ast_timeout=120 seconds. See the
API and metric definitions for details.
Contributing and license
See CONTRIBUTING.md for development and PUBLICATION_CHECKLIST.md for release preparation. The project uses the MIT license, copyright 2026 Otávio Gomes.
Compatibility
Arbitrary distinct nonempty group names are
accepted; use result.within_group_columns to locate collision-safe within-group
means. Keep files unchanged while an analysis runs; optional JavaScript results
with different input hashes raise AnalysisError.
Runtime minimums are scikit-learn 1.5.0 and Pygments 2.20.0; build minimum is setuptools 83.0.0 and development tests require pytest 9.0.3. These scopes are separate. See API and metric limits.
Python AST normalization now uses v3 to identify corrected empty-program behavior. The TED formula ID remains v2; use compatible normalization IDs when comparing results across versions.
Metadata
Release files for codevariability 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| codevariability-0.2.0.tar.gz | 66.5 kB | With provenance | Details for codevariability-0.2.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| codevariability-0.2.0-py3-none-any.whl | Python 3 | none | any | Details for codevariability-0.2.0-py3-none-any.whl |
Total release size: 104.7 kB
Release files / codevariability-0.2.0.tar.gz
| Download URL | codevariability-0.2.0.tar.gz |
|---|---|
| Size | 66.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
bb530ba67f96bd78cd4c75b154ee7c2f27ed86cbd097614aa348dbfdf5c4582a
|
|
BLAKE2b-256 checksum How to use checksums |
983b398ff50940bd964439f735e94d3a57922973d59b053f00e847c98dd5d3f8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 3, 2026.
Transparency logRelease files / codevariability-0.2.0-py3-none-any.whl
| Download URL | codevariability-0.2.0-py3-none-any.whl |
|---|---|
| Size | 38.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f50a612a60cb260f200a5b8282ef456993644be8fda982e430aed44eae7fc809
|
|
BLAKE2b-256 checksum How to use checksums |
bf22221e0bac5f569ca4a1bb8ec4a64e9ee9aec4bf6da8ff9238766097d2b672
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 3, 2026.
Transparency logSecurity for codevariability 0.2.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
Both files in this release have been uploaded with provenance metadata.
Attestation for codevariability-0.2.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 3, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.