Skip to main content

Rust-backed exact tandem-repeat detection for Python strings

Project description

tandem-repeat

Rust-backed Python package for exact tandem-repeat detection in Unicode text.

from tandem_repeat import find, find_longest, find_primitive

find("abcabcabc")
# [TandemRepeat(start=0, end=9, substring='abc', repeats=3, ...), ...]

find("aaaaa")
# [TandemRepeat(start=0, end=5, substring='a', repeats=5, ...),
#  TandemRepeat(start=0, end=4, substring='aa', repeats=2, ...), ...]

find_primitive("aaaaa")
# [TandemRepeat(start=0, end=5, substring='a', repeats=5, ...)]

find_longest("xxabcabcabc")
# TandemRepeat(start=2, end=11, substring='abc', repeats=3, ...)

API

find(
    text: str,
    *,
    min_length: int = 1,
    min_repeats: int = 2,
    max_results: int | None = None,
) -> list[TandemRepeat]

find_primitive(
    text: str,
    *,
    min_length: int = 1,
    min_repeats: int = 2,
    max_results: int | None = None,
) -> list[TandemRepeat]

find_longest(
    text: str,
    *,
    min_length: int = 1,
    min_repeats: int = 2,
) -> TandemRepeat | None

TandemRepeat is a frozen dataclass:

@dataclass(frozen=True, slots=True)
class TandemRepeat:
    start: int       # Python character offset, inclusive
    end: int         # Python character offset, exclusive
    substring: str   # repeated unit
    repeats: int     # number of consecutive copies
    period: int      # len(substring) in Python characters
    byte_start: int  # UTF-8 byte offset, inclusive
    byte_end: int    # UTF-8 byte offset, exclusive

The detector works on the exact input code points. It does not normalize text, so precomposed and decomposed Unicode sequences are treated as different strings.

Complexity

find returns a compact vocabulary-style representation, not every occurrence position. This follows the distinction in Stoye and Gusfield's tandem repeat work: the occurrence set can be quadratic, while the vocabulary of tandem repeat types is linear-size. For example, "aaaaa" includes tandem types such as "a" repeated five times and "aa" repeated twice, but it does not expand every overlapping occurrence into separate Python objects.

find_primitive exposes the practical smaller-subunit view explicitly. It normalizes each block to its smallest repeated unit, so "aaaaa" is represented as "a" repeated five times.

The Rust scanner avoids the old all-periods-by-all-starts search for larger inputs. It scans short periods directly and discovers longer-period candidates from repeated fixed-width seeds, then verifies candidates exactly before returning them. This gives near-linear scaling on sparse realistic text while preserving exact compact blocks for emitted results. Dense fully periodic text uses a separate linear fast path for find_longest.

find_longest returns one result and avoids result-set explosion. On sparse text the benchmark suite now covers inputs up to 100k characters; on dense text it covers 100k-character fully periodic inputs.

Reference:

  • Jens Stoye and Dan Gusfield, "Linear time algorithms for finding and representing all the tandem repeats in a string", JCSS 2004.

Development

This project uses uv, maturin, Rust, Ruff, mypy, and pre-commit.

uv sync --all-extras --dev
uv run maturin develop
uv run pre-commit run --all-files
cargo test
cargo clippy --all-targets -- -D warnings
cargo fmt --check
uv run pytest -q
uv run python benches/bench_scaling.py
uv run python benches/capture_scaling.py

For contribution rules, test expectations, and the release checklist, see CONTRIBUTING.md.

Release

Releases are tag-driven and published by GitHub Actions with PyPI Trusted Publishing. Configure the PyPI trusted publisher for repository dkajtoch/tandem-repeat, workflow .github/workflows/release.yaml, and the protected GitHub environment pypi.

git tag v0.1.0
git push origin v0.1.0

The workflow runs the full Python and Rust quality gates, builds an sdist plus Linux and macOS wheels, validates artifacts with twine check, and publishes from the protected pypi environment.

Benchmarks

The benchmark scripts cover:

  • scaling with text length,
  • scaling with the number of inserted repeat blocks,
  • dense periodic input such as "a" * n,
  • multilingual Arabic, Hebrew, Hindi, CJK, emoji, and mixed-direction text.

The plotted scaling run writes artifacts to bench-results/scaling.csv, bench-results/summary.md, and bench-results/scaling.svg.

Latest local scaling run:

  • Python: 3.11.7
  • Platform: macOS-26.4.1-arm64-arm-64bit
  • Median of 3 trials where noted
  • find and find_primitive capped at 50,000 returned blocks
scenario operation 1k chars 10k chars 50k chars 100k chars 100k results note
sparse random text with one inserted repeat find 0.0050s 0.0577s 0.3145s 0.6650s 1,520 compact vocabulary output
sparse random text with one inserted repeat find_longest 0.0050s 0.0583s 0.3134s 0.6624s 1 same sparse scan, one result
dense single-character periodic text find_longest 0.00008s 0.00070s 0.00355s 0.00686s 1 whole-text fast path
truncated periodic text: ("aab" * n)[:chars] find_primitive 0.0073s 0.1054s 0.4404s 0.9101s 33,336 output-sensitive primitive blocks
dense single-character periodic text find 0.0012s 0.0881s 2.0210s timeout - many vocabulary blocks; 15s timeout

These timings are machine-local measurements, not portable guarantees. The right bound for result-returning methods is output-sensitive: O(n + output) is the practical target for find_primitive, while find can return many compact vocabulary blocks on low-entropy input. find_longest avoids result-set growth because it returns only one block.

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

tandem_repeat-0.1.0.tar.gz (91.1 kB view details)

Uploaded Source

Built Distributions

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

tandem_repeat-0.1.0-cp313-cp313-manylinux_2_28_x86_64.whl (284.2 kB view details)

Uploaded CPython 3.13manylinux: glibc 2.28+ x86-64

tandem_repeat-0.1.0-cp313-cp313-macosx_11_0_arm64.whl (241.9 kB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

tandem_repeat-0.1.0-cp313-cp313-macosx_10_13_x86_64.whl (250.9 kB view details)

Uploaded CPython 3.13macOS 10.13+ x86-64

tandem_repeat-0.1.0-cp312-cp312-manylinux_2_28_x86_64.whl (284.2 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.28+ x86-64

tandem_repeat-0.1.0-cp312-cp312-macosx_11_0_arm64.whl (241.9 kB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

tandem_repeat-0.1.0-cp312-cp312-macosx_10_13_x86_64.whl (250.9 kB view details)

Uploaded CPython 3.12macOS 10.13+ x86-64

tandem_repeat-0.1.0-cp311-cp311-manylinux_2_28_x86_64.whl (284.8 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.28+ x86-64

tandem_repeat-0.1.0-cp311-cp311-macosx_11_0_arm64.whl (244.0 kB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

tandem_repeat-0.1.0-cp311-cp311-macosx_10_12_x86_64.whl (252.8 kB view details)

Uploaded CPython 3.11macOS 10.12+ x86-64

tandem_repeat-0.1.0-cp310-cp310-manylinux_2_28_x86_64.whl (285.1 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.28+ x86-64

tandem_repeat-0.1.0-cp310-cp310-macosx_11_0_arm64.whl (244.2 kB view details)

Uploaded CPython 3.10macOS 11.0+ ARM64

tandem_repeat-0.1.0-cp310-cp310-macosx_10_12_x86_64.whl (253.0 kB view details)

Uploaded CPython 3.10macOS 10.12+ x86-64

File details

Details for the file tandem_repeat-0.1.0.tar.gz.

File metadata

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

File hashes

Hashes for tandem_repeat-0.1.0.tar.gz
Algorithm Hash digest
SHA256 0c7108b4666b54fa4419950ced006edcadab18d13b2f1dc3a6333855f8656a1d
MD5 457e58f6dc567b5eb3ce040f88dbe617
BLAKE2b-256 ee481c1ba39e071a3f706fa236c9db7563143c56320cec4f3daabe364b9a026d

See more details on using hashes here.

Provenance

The following attestation bundles were made for tandem_repeat-0.1.0.tar.gz:

Publisher: release.yaml on dkajtoch/tandem-repeat

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

File details

Details for the file tandem_repeat-0.1.0-cp313-cp313-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for tandem_repeat-0.1.0-cp313-cp313-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 5b7781dd315466e218e89ed9f321c7967ab570299854a4b9bbe7df075a346a87
MD5 31ddc28be9a335ff3deecadd5b165d47
BLAKE2b-256 2f22b20650ab54f2302bf5072aabc16c43fbba917d0d03169bba0cdb61adc56f

See more details on using hashes here.

Provenance

The following attestation bundles were made for tandem_repeat-0.1.0-cp313-cp313-manylinux_2_28_x86_64.whl:

Publisher: release.yaml on dkajtoch/tandem-repeat

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

File details

Details for the file tandem_repeat-0.1.0-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for tandem_repeat-0.1.0-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 a95dba9030f116278b4969bb4f613b56c78d91a2c28dc6252e339918151261b0
MD5 8ba71f2b65a9658796268f01e19de88c
BLAKE2b-256 cbad36899bfccf01b339eb89621d12687adc562e449670ba91f9a2b3031c6d97

See more details on using hashes here.

Provenance

The following attestation bundles were made for tandem_repeat-0.1.0-cp313-cp313-macosx_11_0_arm64.whl:

Publisher: release.yaml on dkajtoch/tandem-repeat

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

File details

Details for the file tandem_repeat-0.1.0-cp313-cp313-macosx_10_13_x86_64.whl.

File metadata

File hashes

Hashes for tandem_repeat-0.1.0-cp313-cp313-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 168bb9d1045e0bfe01eb043bf0c2596125d9b737c5d28b399e103193c4aa1741
MD5 598d5470184cd9173c02a00575e71b98
BLAKE2b-256 0e3355e486344b588b1a061ee934a410475b1d566972fb14049846846bde2611

See more details on using hashes here.

Provenance

The following attestation bundles were made for tandem_repeat-0.1.0-cp313-cp313-macosx_10_13_x86_64.whl:

Publisher: release.yaml on dkajtoch/tandem-repeat

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

File details

Details for the file tandem_repeat-0.1.0-cp312-cp312-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for tandem_repeat-0.1.0-cp312-cp312-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 142238b64c3abb68956c93301bfd358d5d9ecb335601f35c6e0ef39b768b4662
MD5 af2298bfa40a4936ed3f6a2c49721276
BLAKE2b-256 3a1d48588a44363f9a88208c98c87a4a2611508cd0ce08258d30bc409046f519

See more details on using hashes here.

Provenance

The following attestation bundles were made for tandem_repeat-0.1.0-cp312-cp312-manylinux_2_28_x86_64.whl:

Publisher: release.yaml on dkajtoch/tandem-repeat

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

File details

Details for the file tandem_repeat-0.1.0-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for tandem_repeat-0.1.0-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 1bc88085425a1c85bd9c27665406abeb6d95e9f6c0a9ded821caa173f54f3cdd
MD5 c1bedaeb81d45b8c64c8c65bf6d64b93
BLAKE2b-256 897988fafda9c1c708df7989f5251c3e954c1431688b39c0ce4feffeb87809a9

See more details on using hashes here.

Provenance

The following attestation bundles were made for tandem_repeat-0.1.0-cp312-cp312-macosx_11_0_arm64.whl:

Publisher: release.yaml on dkajtoch/tandem-repeat

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

File details

Details for the file tandem_repeat-0.1.0-cp312-cp312-macosx_10_13_x86_64.whl.

File metadata

File hashes

Hashes for tandem_repeat-0.1.0-cp312-cp312-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 14d531a3aeb873580e8157460a52c45ce12b25f81a1263e8d5f6642c937b3958
MD5 d4e1930dde21d2db4bf49d549f12651f
BLAKE2b-256 fba5b309af920b1b71fc20d8b004c2ec4bfd775215d3db5f7473094f579e3816

See more details on using hashes here.

Provenance

The following attestation bundles were made for tandem_repeat-0.1.0-cp312-cp312-macosx_10_13_x86_64.whl:

Publisher: release.yaml on dkajtoch/tandem-repeat

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

File details

Details for the file tandem_repeat-0.1.0-cp311-cp311-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for tandem_repeat-0.1.0-cp311-cp311-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 b6ebc9d754d314b4654dc4fd8363bc15b8b59884fc1b675ec040b5407486e757
MD5 a724f62ebb99841ee938c8bc399ab9d2
BLAKE2b-256 b33aec5d40f1cd6b80e5385e0d18cbd3c8ac18f94cb0426f8b4f80321665ca74

See more details on using hashes here.

Provenance

The following attestation bundles were made for tandem_repeat-0.1.0-cp311-cp311-manylinux_2_28_x86_64.whl:

Publisher: release.yaml on dkajtoch/tandem-repeat

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

File details

Details for the file tandem_repeat-0.1.0-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for tandem_repeat-0.1.0-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 1f46b0e7f26bfd6401e48fa4d32cbaa34b87eadaf527d2711295d935e18b03bf
MD5 6740c4480c8dbd0fd1de2b149ac4b4e8
BLAKE2b-256 4b26b34aa2d69680026fef5a7da777113cbd943bf968cf6f535254eda5556888

See more details on using hashes here.

Provenance

The following attestation bundles were made for tandem_repeat-0.1.0-cp311-cp311-macosx_11_0_arm64.whl:

Publisher: release.yaml on dkajtoch/tandem-repeat

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

File details

Details for the file tandem_repeat-0.1.0-cp311-cp311-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for tandem_repeat-0.1.0-cp311-cp311-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 71c51ff2914c49cdab89e11cb29693c0fdb3ebbe57da471fe783fb20b3378f7b
MD5 6ee9491c8a69c0ceb4b62fcafbb2f052
BLAKE2b-256 9aeab943b164bc6d8ab761a9dcf43db214bb6a4cb1cf23b74558eb9c967d62c0

See more details on using hashes here.

Provenance

The following attestation bundles were made for tandem_repeat-0.1.0-cp311-cp311-macosx_10_12_x86_64.whl:

Publisher: release.yaml on dkajtoch/tandem-repeat

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

File details

Details for the file tandem_repeat-0.1.0-cp310-cp310-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for tandem_repeat-0.1.0-cp310-cp310-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 56607504fef1baf3a38373ef5eb713a7b1f670b5a7d5db42380271c0deb00d0b
MD5 2223c19ed937f0c4257faca7b9f38b7e
BLAKE2b-256 edb065b71f19c0b5287fb6479599307a4cf621ed3981a6169822b25a837493da

See more details on using hashes here.

Provenance

The following attestation bundles were made for tandem_repeat-0.1.0-cp310-cp310-manylinux_2_28_x86_64.whl:

Publisher: release.yaml on dkajtoch/tandem-repeat

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

File details

Details for the file tandem_repeat-0.1.0-cp310-cp310-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for tandem_repeat-0.1.0-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 5d81cfdd56b18a4435cf1e9228bfa91b0391adc567f0b176d337b26b727589c5
MD5 caea4c95771868001399822d610a4edc
BLAKE2b-256 1cdde77a434f595599bb542e612ac832a22fc687659ce46bfe73e21f2fe4c324

See more details on using hashes here.

Provenance

The following attestation bundles were made for tandem_repeat-0.1.0-cp310-cp310-macosx_11_0_arm64.whl:

Publisher: release.yaml on dkajtoch/tandem-repeat

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

File details

Details for the file tandem_repeat-0.1.0-cp310-cp310-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for tandem_repeat-0.1.0-cp310-cp310-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 569de466cb1be36bbe0b1df2ee893904f39f5d0dfe0de033565d79c534161103
MD5 99195beb9248c92c76ac4725d7e2aee3
BLAKE2b-256 7bd5f75590c8b2c8ea6713ede18e037d56e8429f01c9ad1f304ea89200ceaccd

See more details on using hashes here.

Provenance

The following attestation bundles were made for tandem_repeat-0.1.0-cp310-cp310-macosx_10_12_x86_64.whl:

Publisher: release.yaml on dkajtoch/tandem-repeat

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