Skip to main content

A tool for analyzing Python code

Project description

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

Project details


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.1.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.1-py3-none-win_amd64.whl (1.5 MB view details)

Uploaded Python 3Windows x86-64

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

Uploaded Python 3manylinux: glibc 2.28+ x86-64

biston-0.5.1-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.1.tar.gz.

File metadata

  • Download URL: biston-0.5.1.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.1.tar.gz
Algorithm Hash digest
SHA256 c59f34800d1eba7311d22db1fed0b9620074fe866a1fe0fe3737b6143e454fcf
MD5 0496f4130c24188fe3f5bc842fc48cdf
BLAKE2b-256 3c1f9317e541b8bccb2f60ae75ed3b2ca5715bc167356a17a2f6a52cac1dd013

See more details on using hashes here.

Provenance

The following attestation bundles were made for biston-0.5.1.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.1-py3-none-win_amd64.whl.

File metadata

  • Download URL: biston-0.5.1-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.1-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 e628829a4e4cf983f453fd617f5c46dd286fefaac0914d52dadb7420e5cc5a36
MD5 a6bad35a29ac106e9b10206a034cfdef
BLAKE2b-256 0243e90cef990a40c735a825931936bbdb8a478ea8e96dd18abaf20102c0506e

See more details on using hashes here.

Provenance

The following attestation bundles were made for biston-0.5.1-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.1-py3-none-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for biston-0.5.1-py3-none-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 574da541f15d728719aa0627948807b5a1368ebccf129d837763f923f9b7ab8c
MD5 84cabe78dddd2de0db8c20b3dcacc758
BLAKE2b-256 1cd116a9a2c68c7911354092a917c44ded7bf0b9d5487e0115214287f03c43aa

See more details on using hashes here.

Provenance

The following attestation bundles were made for biston-0.5.1-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.1-py3-none-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for biston-0.5.1-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 dd8a6eb4af7c37a6e88ca71be1de4ef43c93cec3111feb878f5af4268d8e2160
MD5 6a4f9836e5ef7cf68398a1c8d89d6cbf
BLAKE2b-256 b619605a2da773d25e3cdd6caf9433d522a9d53cb5a610fa641b7c387fc7256d

See more details on using hashes here.

Provenance

The following attestation bundles were made for biston-0.5.1-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.

Supported by

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