Skip to content

Add kmers, canonical_kmers, bit_kmers to the Python API - #124

Draft
audy wants to merge 3 commits into
masterfrom
python-kmers
Draft

audy wants to merge 3 commits into
masterfrom
python-kmers

Conversation

@audy

@audy audy commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor

Description

  • Add kmers(seq, k) and canonical_kmers(seq, k) module functions, plus Record.kmers(k) and Record.canonical_kmers(k) methods, wrapping the existing Rust Kmers and CanonicalKmers iterators. They return lazy Python iterators. Each one owns a copy of the sequence, and self_cell pairs that buffer with the borrowing Rust iterator. self_cell is a new optional dependency, enabled only by the python and python_test features. Stubs, tests, and a CHANGELOG entry are included. b59b2a6
  • Add bit_kmers(seq, k, canonical=False) and Record.bit_kmers(k, canonical=False), wrapping BitNuclKmer to yield 2-bit packed u64 k-mers (A=0, C=1, G=2, T=3) as (position, int, was_rc) tuples. 8d8ec1b
  • Document the new methods and functions in the README's Python section. 01eb04c

Notes

  • canonical_kmers and bit_kmers skip windows containing non-ACGT bases. For palindromic k-mers, canonical_kmers sets the reverse-complement flag to True and bit_kmers sets it to False. Both match the Rust behavior.
  • Neither function validates that the input is a nucleotide sequence, matching the Rust code. The docstrings note that protein input gives meaningless results rather than an error.
  • k == 0 raises ValueError; k > 255 raises OverflowError. bit_kmers additionally raises ValueError for k > 32. These are raised when the function is called, not on first iteration.

Benchmark

Iterating a random 5 Mb sequence at k=31 (release builds, Apple Silicon), compared with an earlier draft that returned lists:

Function List: time Iterator: time List: time to first item Iterator: time to first item List: extra peak RSS Iterator: extra peak RSS
kmers 0.50 s 0.48 s 367 ms 0.8 ms 688 MB 5 MB
canonical_kmers 1.26 s 0.65 s 824 ms 2.6 ms 1329 MB 10 MB
bit_kmers(canonical=True) 0.72 s 0.43 s 535 ms 0.2 ms 892 MB 5 MB

@audy
audy marked this pull request as ready for review November 7, 2026 00:07
@audy audy changed the title Expose kmers and canonical_kmers in the Python API Add kmers, canonical_kmers, bit_kmers to the Python API Nov 7, 2026
@audy
audy marked this pull request as draft November 7, 2026 00:13
audy added 3 commits November 6, 2026 16:18
Both return lazy iterators that own a copy of the sequence, using self_cell to pair the owned buffer with the borrowing Rust iterator.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant