Skip to content

Commit bfeecd3

Browse files
sullivanj91claude
andcommitted
fix: suppress ty 0.0.27 type errors and move prior_count after as_pandas
- _math.py: update prange type: ignore to bare form (ty 0.0.27 changed error code from attr-defined to not-iterable for nb.prange) - __init__.py: update adata.X subscript type: ignore to bare form (ty 0.0.27 stricter on ZappyArray subscripting); move prior_count param after as_pandas to preserve positional backward compatibility - test_pdex.py: add isinstance narrowing before DataFrame.equals() call to satisfy ty's union type check - CLAUDE.md: update signature to match new param order Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 24bdc90 commit bfeecd3

4 files changed

Lines changed: 12 additions & 10 deletions

File tree

CLAUDE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ uv run ty check
3636

3737
### Core Pipeline (`src/pdex/__init__.py`)
3838

39-
The main entry point is `pdex(adata, groupby, mode, threads, is_log1p, geometric_mean, prior_count, as_pandas, **kwargs)`, which:
39+
The main entry point is `pdex(adata, groupby, mode, threads, is_log1p, geometric_mean, as_pandas, prior_count, **kwargs)`, which:
4040

4141
1. Validates the `groupby` column in `adata.obs`
4242
2. Extracts unique groups (filters NaN and empty strings)

src/pdex/__init__.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -129,9 +129,9 @@ def _isolate_matrix(
129129
if adata.X is None:
130130
raise ValueError("AnnData object does not have a matrix.")
131131
if mask_y is None:
132-
result = adata.X[mask_x] # type: ignore[not-subscriptable]
132+
result = adata.X[mask_x] # type: ignore
133133
else:
134-
result = adata.X[mask_x, mask_y] # type: ignore[not-subscriptable]
134+
result = adata.X[mask_x, mask_y] # type: ignore
135135

136136
# Fast path: already in-memory
137137
if isinstance(result, (np.ndarray, csr_matrix)):
@@ -150,8 +150,8 @@ def pdex(
150150
threads: int = 0,
151151
is_log1p: bool | None = None,
152152
geometric_mean: bool = True,
153-
prior_count: float = 0.0,
154153
as_pandas: bool = False,
154+
prior_count: float = 0.0,
155155
**kwargs,
156156
) -> pl.DataFrame | pd.DataFrame:
157157
"""Run parallel differential expression analysis on single-cell data.
@@ -199,15 +199,15 @@ def pdex(
199199
``is_log1p=True`` the data is back-transformed before averaging
200200
(``mean(expm1(X))``) so the output is consistent regardless of input
201201
format.
202+
as_pandas:
203+
If ``True``, return a :class:`pandas.DataFrame` instead of a
204+
:class:`polars.DataFrame`. Requires ``pyarrow``.
202205
prior_count:
203206
Pseudocount added to both ``target_mean`` and ``ref_mean`` before computing
204207
``fold_change``. When ``prior_count > 0``, extreme fold changes from near-zero
205208
reference means (scRNA-seq sparsity artifact) are dampened toward zero.
206209
Has no effect on the Mann-Whitney U p-value or FDR.
207210
Default ``0.0`` preserves existing behaviour.
208-
as_pandas:
209-
If ``True``, return a :class:`pandas.DataFrame` instead of a
210-
:class:`polars.DataFrame`. Requires ``pyarrow``.
211211
**kwargs:
212212
Mode-specific keyword arguments:
213213

src/pdex/_math.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ def _log1p_col_mean(matrix: np.ndarray) -> np.ndarray:
1414
"""Mean of log1p(X) across rows (axis=0) for a dense 2-D array."""
1515
n_rows, n_cols = matrix.shape
1616
result = np.zeros(n_cols)
17-
for j in nb.prange(n_cols): # type: ignore[attr-defined]
17+
for j in nb.prange(n_cols): # type: ignore
1818
s = 0.0
1919
for i in range(n_rows):
2020
s += np.log1p(matrix[i, j])
@@ -26,7 +26,7 @@ def _log1p_col_mean(matrix: np.ndarray) -> np.ndarray:
2626
def _expm1_vec(x: np.ndarray) -> np.ndarray:
2727
"""Element-wise expm1 over a 1-D array."""
2828
result = np.empty_like(x)
29-
for i in nb.prange(len(x)): # type: ignore[attr-defined]
29+
for i in nb.prange(len(x)): # type: ignore
3030
result[i] = np.expm1(x[i])
3131
return result
3232

@@ -36,7 +36,7 @@ def _expm1_vec_mean(matrix: np.ndarray) -> np.ndarray:
3636
"""Mean of expm1(X) across rows (axis=0) for a dense 2-D array."""
3737
n_rows, n_cols = matrix.shape
3838
result = np.zeros(n_cols)
39-
for j in nb.prange(n_cols): # type: ignore[attr-defined]
39+
for j in nb.prange(n_cols): # type: ignore
4040
s = 0.0
4141
for i in range(n_rows):
4242
s += np.expm1(matrix[i, j])

tests/test_pdex.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,8 @@ def test_prior_count_zero_matches_default(self, small_adata):
148148
explicit_result = pdex(
149149
small_adata, groupby="guide", is_log1p=False, prior_count=0.0
150150
)
151+
assert isinstance(default_result, pl.DataFrame)
152+
assert isinstance(explicit_result, pl.DataFrame)
151153
assert default_result.equals(explicit_result)
152154

153155

0 commit comments

Comments
 (0)