From d5274d92f9827d8bad40f90c0e36d56f1c672613 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ant=C3=B4nio=20Camargo?= Date: Sun, 26 Oct 2025 03:26:42 -0700 Subject: [PATCH 1/6] Build for Python 3.14 --- .github/workflows/release.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 19f54fc..7f3f83b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -33,6 +33,7 @@ jobs: - "3.11" - "3.12" - "3.13" + - "3.14" steps: - uses: actions/checkout@v4 - name: Build wheels @@ -63,6 +64,7 @@ jobs: - "3.11" - "3.12" - "3.13" + - "3.14" steps: - uses: actions/checkout@v4 - name: Build wheels From f5d8b9d82fcbb5f5b83fd48309e1934c00e4d0be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ant=C3=B4nio=20Camargo?= Date: Sun, 26 Oct 2025 03:41:08 -0700 Subject: [PATCH 2/6] Bump PyO3 to 0.27.1 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 4d3461f..9d0a1b4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,7 +31,7 @@ bytecount = { version = "0.6", features = ["runtime-dispatch-simd"] } bzip2 = { version = "0.4", optional = true } flate2 = { version = "1.0.30", optional = true } memchr = "2.7.2" -pyo3 = { version = "0.24.1", optional = true } +pyo3 = { version = "0.27.1", optional = true } liblzma = { version = "0.3.1", optional = true } zstd = { version = "0.13.2", optional = true } From 8280de5c60d3151a68da7da5624e3dd987933364 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ant=C3=B4nio=20Camargo?= Date: Wed, 10 Dec 2025 09:19:08 -0300 Subject: [PATCH 3/6] Update maturin and PyO3 --- .github/workflows/release.yml | 5 ----- Cargo.toml | 2 +- pyproject.toml | 2 +- 3 files changed, 2 insertions(+), 7 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7f3f83b..25f9f85 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,8 +1,3 @@ -# This file is autogenerated by maturin v1.8.2 -# To update, run -# -# maturin generate-ci github -# name: build wheels on: diff --git a/Cargo.toml b/Cargo.toml index 9d0a1b4..580f2a5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,7 +31,7 @@ bytecount = { version = "0.6", features = ["runtime-dispatch-simd"] } bzip2 = { version = "0.4", optional = true } flate2 = { version = "1.0.30", optional = true } memchr = "2.7.2" -pyo3 = { version = "0.27.1", optional = true } +pyo3 = { version = "0.27.2", optional = true } liblzma = { version = "0.3.1", optional = true } zstd = { version = "0.13.2", optional = true } diff --git a/pyproject.toml b/pyproject.toml index e61223d..fcd9a72 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [build-system] -requires = ["maturin>=1.8,<2.0"] +requires = ["maturin>=1.10,<2.0"] build-backend = "maturin" [project] From ee820538d46d8b23cb150484df75d19e5d0fa527 Mon Sep 17 00:00:00 2001 From: Antonio Camargo Date: Wed, 10 Dec 2025 09:40:20 -0300 Subject: [PATCH 4/6] Fix Clippy lints in Python bindings --- src/python.rs | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/python.rs b/src/python.rs index 0b09357..bfe9ab7 100644 --- a/src/python.rs +++ b/src/python.rs @@ -38,7 +38,7 @@ fn get_seq_snippet(seq: &str, max_len: usize) -> String { if seq.len() > max_len { let start = &seq[..max_len - 4]; let end = &seq[seq.len() - 3..]; - format!("{}…{}", start, end) + format!("{start}…{end}") } else { seq.to_string() } @@ -156,7 +156,7 @@ impl Record { #[getter] pub fn description(&self) -> PyResult> { if let Some(pos) = self.id.find(char::is_whitespace) { - Ok(Some(&self.id[pos..].trim_start())) + Ok(Some(self.id[pos..].trim_start())) } else { Ok(None) } @@ -219,9 +219,8 @@ impl Record { let mut hasher = DefaultHasher::new(); self.id.hash(&mut hasher); self.seq.hash(&mut hasher); - match &self.qual { - Some(qual) => qual.hash(&mut hasher), - None => {} + if let Some(qual) = &self.qual { + qual.hash(&mut hasher); } Ok(hasher.finish()) } @@ -249,7 +248,7 @@ impl Record { fn __repr__(&self) -> PyResult { let id_snippet = match self.name() { - Ok(name) if name != self.id => format!("{}…", name), + Ok(name) if name != self.id => format!("{name}…"), Ok(name) => name.to_string(), Err(_) => self.id.clone(), }; @@ -259,8 +258,7 @@ impl Record { None => "None".to_string(), }; Ok(format!( - "Record(id={}, seq={}, qual={})", - id_snippet, seq_snippet, quality_snippet + "Record(id={id_snippet}, seq={seq_snippet}, qual={quality_snippet})" )) } } @@ -424,7 +422,7 @@ pub fn py_decode_phred(qual: &str, base_64: bool, py: Python<'_>) -> PyResult Date: Wed, 10 Dec 2025 09:50:26 -0300 Subject: [PATCH 5/6] Use explicit lifetimes --- src/parser/fasta.rs | 2 +- src/parser/fastq.rs | 2 +- src/parser/record.rs | 2 +- src/parser/utils.rs | 2 +- src/sequence.rs | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/parser/fasta.rs b/src/parser/fasta.rs index 53f4d62..40f2a22 100644 --- a/src/parser/fasta.rs +++ b/src/parser/fasta.rs @@ -288,7 +288,7 @@ where } impl FastxReader for Reader { - fn next(&mut self) -> Option> { + fn next(&mut self) -> Option, ParseError>> { if self.finished { return None; } diff --git a/src/parser/fastq.rs b/src/parser/fastq.rs index ce1a274..d5c6642 100644 --- a/src/parser/fastq.rs +++ b/src/parser/fastq.rs @@ -385,7 +385,7 @@ where } impl FastxReader for Reader { - fn next(&mut self) -> Option> { + fn next(&mut self) -> Option, ParseError>> { // No more records to read if self.finished { return None; diff --git a/src/parser/record.rs b/src/parser/record.rs index 75427f9..f4356be 100644 --- a/src/parser/record.rs +++ b/src/parser/record.rs @@ -84,7 +84,7 @@ impl<'a> SequenceRecord<'a> { /// Returns the cleaned up sequence of the record. For FASTQ it is the same as `raw_seq` but /// for FASTA it is `raw_seq` minus all the `\r\n` - pub fn seq(&self) -> Cow<[u8]> { + pub fn seq(&self) -> Cow<'_, [u8]> { match self.buf_pos { BufferPositionKind::Fasta(bp) => bp.seq(self.buffer), BufferPositionKind::Fastq(bp) => bp.seq(self.buffer).into(), diff --git a/src/parser/utils.rs b/src/parser/utils.rs index 5d169fc..781c876 100644 --- a/src/parser/utils.rs +++ b/src/parser/utils.rs @@ -120,7 +120,7 @@ pub trait FastxReader: Send { /// Gets the next record in the stream. /// This imitates the Iterator API but does not support any iterator functions. /// This returns None once we reached the EOF. - fn next(&mut self) -> Option>; + fn next(&mut self) -> Option, ParseError>>; /// Returns the current line/byte in the stream we are reading from fn position(&self) -> &Position; /// Returns whether the current stream uses Windows or Unix style line endings diff --git a/src/sequence.rs b/src/sequence.rs index 6dc37af..af69d92 100644 --- a/src/sequence.rs +++ b/src/sequence.rs @@ -107,7 +107,7 @@ pub fn complement(n: u8) -> u8 { /// Taking in a sequence string, return the canonical form of the sequence /// (e.g. the lexigraphically lowest of either the original sequence or its /// reverse complement) -pub fn canonical(seq: &[u8]) -> Cow<[u8]> { +pub fn canonical(seq: &[u8]) -> Cow<'_, [u8]> { let mut buf: Vec = Vec::with_capacity(seq.len()); // enough just keeps our comparisons from happening after they need to let mut enough = false; @@ -136,7 +136,7 @@ pub fn canonical(seq: &[u8]) -> Cow<[u8]> { /// Find the lexigraphically smallest substring of `seq` of length `length` /// /// There's probably a faster algorithm for this somewhere... -pub fn minimizer(seq: &[u8], length: usize) -> Cow<[u8]> { +pub fn minimizer(seq: &[u8], length: usize) -> Cow<'_, [u8]> { let reverse_complement: Vec = seq.iter().rev().map(|n| complement(*n)).collect(); let mut minmer = Cow::Borrowed(&seq[..length]); From 1bdeda9b3a7f5975b0db053a8168bfa7f2f206e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ant=C3=B4nio=20Camargo?= Date: Wed, 10 Dec 2025 08:30:38 -0800 Subject: [PATCH 6/6] Update macOS runners --- .github/workflows/release.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 25f9f85..c820eab 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -49,9 +49,9 @@ jobs: strategy: matrix: platform: - - runner: macos-13 + - runner: macos-15 target: x86_64 - - runner: macos-14 + - runner: macos-15 target: aarch64 python-version: - "3.9"