Skip to main content

biston

A structural clone detector for Python code. Written in Rust.

It parses Python files with tree-sitter, normalizes the AST, and finds functions that are structurally similar to each other.

Install

uv add biston

Or build from source:

cargo build --release

Usage

biston <COMMAND>

Commands

biston scan

Scan a directory for code clones.

Usage: biston scan [OPTIONS] [PATH]

Arguments:
  [PATH]  Directory to scan [default: .]

Options:
      --format <FORMAT>        Output format [possible values: text, json, sarif]
      --min-lines <MIN_LINES>  Minimum function length in lines
      --threshold <THRESHOLD>  Similarity threshold (0.0 - 1.0)
      --config <CONFIG>        Config file directory (looks for biston.toml or pyproject.toml)
      --tests-only             Restrict the scan to Python test files (overrides include/exclude)
      --suggest                Generate abstraction suggestions for similar pairs
      --files <FILE>           Only emit pairs involving this file (repeat for multiple)
      --files-from <PATH>      Read focus file list from PATH, or `-` for stdin
  -h, --help                   Print help

biston stats

Show statistics about scan findings.

Usage: biston stats [OPTIONS] [PATH]

Arguments:
  [PATH]  Directory to scan [default: .]

Options:
      --format <FORMAT>        Output format [possible values: text, json, sarif]
      --min-lines <MIN_LINES>  Minimum function length in lines
      --threshold <THRESHOLD>  Similarity threshold (0.0 - 1.0)
      --config <CONFIG>        Config file directory (looks for biston.toml or pyproject.toml)
      --tests-only             Restrict the scan to Python test files (overrides include/exclude)
      --files <FILE>           Only emit pairs involving this file (repeat for multiple)
      --files-from <PATH>      Read focus file list from PATH, or `-` for stdin
  -h, --help                   Print help
Scanning tests only

Test suites often accumulate duplication (near-identical cases that could be @pytest.mark.parametrize, copy-pasted arrange/act/assert blocks). By default biston excludes test files so production-code findings stay focused. Pass --tests-only to flip the scope and scan only test files:

biston scan --tests-only
biston stats --tests-only

The flag replaces include with common Python test patterns (**/test_*.py, **/*_test.py, **/conftest.py, tests/**/*.py) and clears exclude. Other knobs (min_lines, threshold, normalization) are left untouched — tune them separately in biston.toml if you want different defaults for a test run.

Commit-hook use (focus files)

--files / --files-from let you restrict reporting to pairs involving a specific set of files, while still scanning the whole repo so cross-file clones between those files and the rest of the tree are detected.

For a pre-commit hook, pipe git diff --name-only through --files-from -:

git diff --name-only --diff-filter=ACM -- '*.py' \
  | biston scan --files-from - .

An empty list (no Python files changed) correctly emits no pairs. Prefer --files-from over --files $(git diff --name-only) — the latter expands to an empty flag when nothing changed, which reverts to a full-repo scan.

Configuration

Settings can go in biston.toml or under [tool.biston] in pyproject.toml. If both files exist, biston.toml takes priority. CLI flags override config file settings.

[scan]

Setting Default Description
min_lines 10 Minimum function length in lines
threshold 0.7 Similarity threshold (0.0–1.0)
exclude ["tests/**", "**/conftest.py", "migrations/**"] File patterns to exclude
include ["**/*.py"] File patterns to include

[normalization]

Setting Default Description
anonymize_locals true Replace local variable names
anonymize_literals false Replace literal values
strip_decorators true Remove decorators from AST
strip_type_annotations true Remove type hints
sort_commutative false Sort commutative operations

[output]

Setting Default Description
format "text" Output format (text, json, or sarif)
group_overlapping true Group overlapping clones
max_results 50 Maximum number of results
show_source true Display source code in output
context_lines 3 Number of context lines around clones

[suggest]

Setting Default Description
enabled false Enable suggestion generation
min_quality 0.6 Minimum template coverage score (0.0–1.0)
max_holes 5 Maximum holes before suppressing
render_python true Render templates as Python source

[suppress]

Setting Default Description
files [] File glob patterns to suppress entirely

Example biston.toml

[scan]
min_lines = 15
threshold = 0.8
exclude = ["vendor/"]
include = ["src/**/*.py"]

[normalization]
anonymize_locals = false
anonymize_literals = true

[output]
format = "json"
max_results = 100

[suggest]
enabled = true
min_quality = 0.8

Inline suppression

You can also suppress findings with Python comments:

  • # biston: ignore-file — suppress the entire file (must appear in the first 5 lines)
  • # biston: ignore — suppress a single function (place in the function body or on the preceding line)

When scan or overview reports clones, the text output ends with a one-line reminder of these options. Run biston usage for the full reference at any time:

biston usage

Documentation

Full docs at https://mojzis.github.io/biston/.

License

MIT

Download files

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

Source Distribution

biston-0.5.3.tar.gz (888.4 kB view details)

Uploaded Source

Built Distributions

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

biston-0.5.3-py3-none-win_amd64.whl (1.5 MB view details)

Uploaded Python 3Windows x86-64

biston-0.5.3-py3-none-manylinux_2_28_x86_64.whl (1.7 MB view details)

Uploaded Python 3manylinux: glibc 2.28+ x86-64

biston-0.5.3-py3-none-macosx_11_0_arm64.whl (1.4 MB view details)

Uploaded Python 3macOS 11.0+ ARM64

File details

Details for the file biston-0.5.3.tar.gz.

File metadata

  • Download URL: biston-0.5.3.tar.gz
  • Upload date:
  • Size: 888.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for biston-0.5.3.tar.gz
Algorithm Hash digest
SHA256 2e161ebce1b5075db6fe1407c3b7154c8be534d4c94023eaff8ef74d105b646e
MD5 568cc376c9c493726c527dc8069d0e6f
BLAKE2b-256 1a67b71f510643bed3c40f6829ba575235f13cd7ba5a0773b3b96a693398e5f7

See more details on using hashes here.

Provenance

The following attestation bundles were made for biston-0.5.3.tar.gz:

Publisher: release.yml on mojzis/biston

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file biston-0.5.3-py3-none-win_amd64.whl.

File metadata

  • Download URL: biston-0.5.3-py3-none-win_amd64.whl
  • Upload date:
  • Size: 1.5 MB
  • Tags: Python 3, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for biston-0.5.3-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 bf02e73b54a2460cc8010c29d420a06f26f98075bd170401315ee74720a40a8f
MD5 a223d410b3ac821c8775acaf419b91ca
BLAKE2b-256 d2822bb2451a3ba8c85f06aad50b738d7d078c3043112385b09d49a97d3cce4c

See more details on using hashes here.

Provenance

The following attestation bundles were made for biston-0.5.3-py3-none-win_amd64.whl:

Publisher: release.yml on mojzis/biston

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file biston-0.5.3-py3-none-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for biston-0.5.3-py3-none-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 a24f368919f18f9b73b44a2078330f0d7c196b077ed688127570125b30f8df97
MD5 f7509502b76989e702e0977678114444
BLAKE2b-256 3fa07176993e447f7ff37c3bd961c1925f921bd27c6259368419f8c471a001b7

See more details on using hashes here.

Provenance

The following attestation bundles were made for biston-0.5.3-py3-none-manylinux_2_28_x86_64.whl:

Publisher: release.yml on mojzis/biston

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file biston-0.5.3-py3-none-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for biston-0.5.3-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 8214161f96d82ff6b9baf429abdf68950986d2402d96ee6e8d72114debf456d8
MD5 441d0f4bbe91a01448bc986a485a962d
BLAKE2b-256 5855dbd31f1b15fbb45d739450b39da6e6d3cb99ff78b3239607ae4cabbda39b

See more details on using hashes here.

Provenance

The following attestation bundles were made for biston-0.5.3-py3-none-macosx_11_0_arm64.whl:

Publisher: release.yml on mojzis/biston

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.6.0

4 files

0.5.5

4 files

0.5.4

4 files

This release

0.5.3 This release

4 files

0.5.2

4 files

0.5.1

4 files

0.5.0

4 files

0.4.0

4 files

0.3.0

4 files

0.2.0

4 files

Supported by

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