Skip to content

Make most arguments keyword-only, enforced by PLR0917 (#1288) - #1297

Open
selmanozleyen wants to merge 5 commits into
mainfrom
chore/kwonly-args
Open

selmanozleyen wants to merge 5 commits into
mainfrom
chore/kwonly-args

Conversation

@selmanozleyen

@selmanozleyen selmanozleyen commented Sep 25, 2026 •

Copy link
Copy Markdown
Member

fixes: #1288 plus I also removed notes-dev.md as it's old. I also added some items to the contribution guide.

The rule: every public function takes only its data object positionally (adata, *, ...), everything after it is keyword-only. Private helpers that take an AnnData or SpatialData first follow the same rule; other private helpers only need to pass PLR0917.

The ones I didn't include:

  • @old_positionals on released public functions: anything in v1.8.3 keeps accepting old positional calls, with a FutureWarning that says the positional form stops working in v1.9.0.
  • None on squidpy.experimental: the experimental API makes no stability promise.
  • None on unreleased functions: the spatial_neighbors_* builders and the Incorporating feedback on niche refactor #1284 niche flavors have no old calls to support.
  • None on private functions: internal callers were updated to pass keywords.
  • calculate_niche left as is: it's deprecated and removed in v1.9.0, and a second wrapper would stack warnings.
  • ImageContainer left as is: it's exempted per file until it's deprecated.

Tests changed because

  • Test calls that passed now-keyword-only arguments positionally were switched to keywords, so they don't hit the FutureWarning or the TypeError.
  • New test: an old positional call still works and warns (tests/utils/test_old_positionals.py).
  • test_niche.py filters calculate_niche's deprecation warning, since those tests exercise the umbrella on purpose until v1.9.0. One test still asserts the warning.
  • Tests are exempt from PLR0917, since pytest passes fixtures by name.

Follow-ups

  • Update the tutorials in squidpy-tutorials: 17 sq.im.calculate_image_features(adata, img, …) calls and 2 sq.gr.centrality_scores(adata, "…") calls, plus positional calls to pl.spatial_scatter, pl.spatial_segment, pl.var_by_distance, pl.extract and tl.sliding_window, now warn.
  • Remove the @old_positionals shims in v1.9.0.
  • Deal with ImageContainer when it's deprecated; it's currently exempt from the rule per file.
  • Replace the deprecated skimage, pandas and anndata calls in src (binary_closing, square, area_threshold, skimage.io plugins, pandas copy=, uns_keys).

@codecov

codecov Bot commented Sep 25, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 94.32624% with 8 lines in your changes missing coverage. Please review.
✅ Project coverage is 78.74%. Comparing base (1936a92) to head (75b4beb).

Files with missing lines Patch % Lines
src/squidpy/gr/_nhood.py 81.81% 4 Missing ⚠️
src/squidpy/gr/_ligrec.py 66.66% 2 Missing ⚠️
src/squidpy/im/_container.py 50.00% 1 Missing ⚠️
src/squidpy/tl/_var_by_distance.py 83.33% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1297      +/-   ##
==========================================
+ Coverage   78.63%   78.74%   +0.10%     
==========================================
  Files          64       64              
  Lines        9604     9653      +49     
  Branches     1613     1613              
==========================================
+ Hits         7552     7601      +49     
  Misses       1497     1497              
  Partials      555      555              
Files with missing lines Coverage Δ
src/squidpy/_compat.py 77.77% <100.00%> (+4.44%) ⬆️
src/squidpy/_utils.py 72.11% <100.00%> (+0.11%) ⬆️
...uidpy/experimental/im/_calculate_image_features.py 89.42% <100.00%> (ø)
src/squidpy/experimental/im/_detect_tissue.py 67.77% <100.00%> (ø)
src/squidpy/experimental/im/_make_tiles.py 73.97% <100.00%> (ø)
src/squidpy/experimental/im/_qc_image.py 82.48% <100.00%> (ø)
src/squidpy/experimental/im/_stain/_normalize.py 93.75% <100.00%> (ø)
src/squidpy/experimental/im/_utils.py 67.26% <ø> (ø)
src/squidpy/experimental/pl/_qc_image.py 60.22% <ø> (ø)
src/squidpy/experimental/pl/_tiling_qc.py 64.70% <ø> (ø)
... and 23 more
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@selmanozleyen
selmanozleyen marked this pull request as draft September 29, 2026 14:11
@selmanozleyen
selmanozleyen marked this pull request as ready for review September 29, 2026 16:06
@selmanozleyen
selmanozleyen requested review from timtreis and removed request for timtreis September 29, 2026 21:47
Ruff's PLR0917 (preview, selected explicitly) now flags any function with
more than five positional arguments.

- Public functions take only their data object positionally; everything
  after it is keyword-only. Released functions keep accepting the old
  positional calls through legacy-api-wrap, with a FutureWarning naming
  the arguments. Experimental functions don't: that API promises no
  stability.
- Private functions change only where the rule flags them: arguments with a
  default become keyword-only, and helpers whose arguments are all required
  keep only their first argument positional. Numba kernels are exempted,
  since numba needs positional arguments.
- Left as on main: the deprecated calculate_niche and its validator (removed
  in v1.9.0), and ImageContainer until it is deprecated.
- Internal and test callers pass the moved arguments by name. Tests are
  exempted from the rule, since pytest passes fixtures by name.
Preview mode also caught an undefined apply_stain_normalization in
squidpy.experimental.im.__all__, removed here.

Also documents these rules and the rng conventions in the contribution
guide, and drops the unused docs/release/notes-dev.md: release notes come
from the PR changelog.

This branch has not been deployed

No deployments
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.

Make most of args kwargs only with PLR0917

1 participant