Skip to content

chore: replace the remaining enums with literals (3/4) - #1286

Open
selmanozleyen wants to merge 28 commits into
mainfrom
feat/enum-to-literal
Open

selmanozleyen wants to merge 28 commits into
mainfrom
feat/enum-to-literal

Conversation

@selmanozleyen

Copy link
Copy Markdown
Member

Continuation of #1279. Because we don't want to expose different classes for this anymore

@selmanozleyen selmanozleyen changed the title replace two enums with literals chore: replace two enums with literals Sep 3, 2026
@selmanozleyen selmanozleyen changed the title chore: replace two enums with literals chore: replace two enums with literals (3/4) Sep 3, 2026
@codecov

codecov Bot commented Sep 3, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 94.64286% with 12 lines in your changes missing coverage. Please review.
✅ Project coverage is 78.97%. Comparing base (f030690) to head (90cb7b5).

Files with missing lines Patch % Lines
src/squidpy/_validators.py 90.00% 0 Missing and 2 partials ⚠️
src/squidpy/experimental/im/_utils.py 66.66% 1 Missing and 1 partial ⚠️
src/squidpy/gr/_ligrec.py 84.61% 1 Missing and 1 partial ⚠️
src/squidpy/experimental/im/_detect_tissue.py 88.88% 0 Missing and 1 partial ⚠️
src/squidpy/experimental/im/_qc_image.py 93.33% 1 Missing ⚠️
src/squidpy/gr/_clusterers.py 75.00% 0 Missing and 1 partial ⚠️
src/squidpy/gr/_nhood.py 95.23% 0 Missing and 1 partial ⚠️
src/squidpy/im/_feature.py 92.30% 0 Missing and 1 partial ⚠️
src/squidpy/pl/_ligrec.py 85.71% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1286      +/-   ##
==========================================
+ Coverage   78.88%   78.97%   +0.08%     
==========================================
  Files          65       63       -2     
  Lines        9611     9437     -174     
  Branches     1591     1574      -17     
==========================================
- Hits         7582     7453     -129     
+ Misses       1497     1466      -31     
+ Partials      532      518      -14     
Files with missing lines Coverage Δ
src/squidpy/_constants/_pkg_constants.py 94.07% <100.00%> (-0.13%) ⬇️
src/squidpy/datasets/_datasets.py 87.71% <100.00%> (-0.22%) ⬇️
...uidpy/experimental/im/_calculate_image_features.py 89.90% <100.00%> (+0.48%) ⬆️
src/squidpy/experimental/im/_qc_metrics.py 100.00% <100.00%> (ø)
src/squidpy/experimental/im/_stain/_normalize.py 95.34% <100.00%> (ø)
src/squidpy/experimental/im/_stain/_reference.py 86.56% <100.00%> (ø)
src/squidpy/experimental/pl/_qc_image.py 69.04% <100.00%> (+8.82%) ⬆️
src/squidpy/experimental/tl/_stitched_labels.py 84.72% <100.00%> (+0.14%) ⬆️
src/squidpy/gr/_build.py 90.20% <100.00%> (-0.35%) ⬇️
src/squidpy/gr/_niche.py 88.55% <100.00%> (+0.55%) ⬆️
... and 19 more
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@selmanozleyen
selmanozleyen force-pushed the feat/stain-reference-methods branch from 1ba759b to d05f6d0 Compare September 15, 2026 16:50
@selmanozleyen
selmanozleyen force-pushed the feat/stain-reference-methods branch 2 times, most recently from b4fb050 to 391f486 Compare September 25, 2026 12:48
@selmanozleyen
selmanozleyen force-pushed the feat/enum-to-literal branch 2 times, most recently from 8002862 to ea84b09 Compare September 25, 2026 16:05
@selmanozleyen
selmanozleyen force-pushed the feat/stain-reference-methods branch from 391f486 to 69a17fe Compare September 25, 2026 16:05
@selmanozleyen
selmanozleyen force-pushed the feat/stain-reference-methods branch from 69a17fe to 2deb8b1 Compare September 25, 2026 19:42
@selmanozleyen
selmanozleyen removed this pull request from stack #1281 September 25, 2026 20:17
@selmanozleyen
selmanozleyen force-pushed the feat/stain-reference-methods branch from 2deb8b1 to 18ee65c Compare September 25, 2026 20:18
@selmanozleyen
selmanozleyen force-pushed the feat/stain-reference-methods branch 2 times, most recently from cc1cbbb to a7bf95b Compare September 25, 2026 21:58
@selmanozleyen
selmanozleyen force-pushed the feat/stain-reference-methods branch from a7bf95b to 178c9af Compare September 25, 2026 22:04
@selmanozleyen
selmanozleyen force-pushed the feat/enum-to-literal branch 2 times, most recently from a6a2231 to f97a55a Compare September 25, 2026 22:28
@selmanozleyen
selmanozleyen force-pushed the feat/stain-reference-methods branch from 178c9af to b5bdc06 Compare September 25, 2026 22:28
@selmanozleyen
selmanozleyen force-pushed the feat/stain-reference-methods branch from b5bdc06 to b1ba20c Compare September 29, 2026 14:58
@selmanozleyen
selmanozleyen force-pushed the feat/stain-reference-methods branch from b1ba20c to 3bcbd1e Compare September 29, 2026 16:05
@selmanozleyen
selmanozleyen force-pushed the feat/stain-reference-methods branch from 3bcbd1e to 44a97a4 Compare October 1, 2026 12:15
@selmanozleyen
selmanozleyen marked this pull request as draft October 9, 2026 17:02
selmanozleyen and others added 22 commits October 9, 2026 19:23
spatial_autocorr(mode), ripley(mode) in gr and pl, spatial_neighbors(coord_type)
and the transform argument on every builder now take plain string literals,
resolved with normalize_choice. Drops ModeEnum._missing_, which only existed to
give those enum-backed arguments the same case-insensitivity.

normalize_choice unwraps Enum members, so CoordType.GRID and Transform.COSINE
keep working for anyone who read them off the released signatures.
Delete four ModeEnum subclasses with no remaining references, drop the
transform normalization _build.py repeated on top of the builders' own, and
remove branches normalize_choice already made unreachable.

gr.ripley loses an @inject_docs that injected nothing, so its LaTeX no longer
needs doubled braces. Option lists that only restate a Literal go; Sphinx
renders the annotation into the signature already. pl.centrality_scores folds
the requested score names against the columns directly instead of catching
ValueError from normalize_choice.

Note in contributing.md which arguments are still enum-backed, and so still
case-sensitive, now that ModeEnum._missing_ is gone.
TransformPostprocessor holds the canonical string, so the last ModeEnum behind
a converted argument goes, along with the Enum unwrap in normalize_choice that
existed only to keep Transform members working from a private module. The uns
payload is unchanged: .v already yielded these same strings and None.
Transform.NONE was the only non-string value, so the str mixin the TODO asked
for now applies cleanly: members compare and hash equal to their value, and
ScatterShape drops its own str prefix. Narrow the TODO to what is left, the 63
.s call sites.

Also say plainly why pl.centrality_scores cannot use normalize_choice: its
valid values are whichever columns gr.centrality_scores wrote.
The score columns are the three Centrality values, a closed set, so the
argument takes a Literal on both the gr and pl side and resolves through
normalize_choice. That retires the enum, the unreachable NotImplementedError
guard over its own three members, and four of the seven real .s call sites.

Correct the contributing note that claimed this one could not have an option
list, and cover gr.centrality_scores in the casing table.
Three call sites caught ValueError to mean "no match": two to word their own
error, one to leave an unmatched name alone. A `default` keyword says that
directly. It takes a sentinel rather than None, since None is itself a legal
option.
The result is always one of the options, so hand that type back instead of Any;
pyright narrows a plain tuple to its literals, so call sites get
Literal['F', 'G', 'L'] rather than losing the type. Two overloads because the
miss returns the default, whose type is unrelated.

Restore the mode option list on pl.nhood_enrichment.
_pretty_raise_enum, ErrorFormatterABC and ABCEnumMeta existed to replace the
stdlib's message with one naming the valid options. A _missing_ that raises
does the same in three lines: CPython propagates it out of Enum.__call__, so
no wrapper, no mixin, no metaclass. Every user of the three was inside this
file.

The message is byte-identical, which the ligrec and image-feature tests pin.
Both arguments also take a callable, so normalize_choice sits behind the
existing isinstance guard and the callable path is untouched. segment keeps
accepting "custom" so passing it as a string still raises the TypeError about
needing a callable, rather than turning into a ValueError.

Key.img.segment and Key.img.process lose their enum round-trip, and the
qc_image metric check drops a comprehension.
A PEP 695 `type` alias is lazily evaluated, so get_args() on it returns
nothing, which is how spatial_scatter ended up normalizing against an empty
option list. Aliases we read back at runtime are plain assignments instead,
and the .__value__ unwrapping goes.
features was the last argument reaching an enum, so _constants/_constants.py
and _constants/_utils.py both go: no more ModeEnum, PrettyEnum, .s or .v.
_pkg_constants.Key stays.

The Literal carries the enum's values, so 'histogram' rather than the
COLOR_HIST member name that would have renamed the output column.
Add the eight missing rows to the casing table: shape, corr_axis,
complex_policy, dendrogram, features, both method arguments and dims. They are
what makes the contributing rule enforced rather than asserted, and shape is
the one this branch already broke once.

options_of leaves a single get_args call in the package and reads a lazy `type`
alias too, so an option list cannot silently come back empty. _as_transform
derives its tuple the same way instead of retyping it.

_check_strategy words its own error rather than mirroring normalize_choice's,
and the two spatial_neighbors parameter docs keep their original wording.
@selmanozleyen selmanozleyen changed the title chore: replace two enums with literals (3/4) chore: replace the remaining enums with literals (3/4) Oct 9, 2026
@selmanozleyen
selmanozleyen marked this pull request as ready for review October 9, 2026 20:26
fit_stain_reference gained multi-slide pooling on main, so that structure wins
and only its method check becomes normalize_choice.

_VALID_METHODS arrived as a frozenset, which left one call site sorting it and
the other printing options in arbitrary order. It is a tuple from options_of
now, so both read in declaration order, and _DECOMPOSITION_METHODS derives from
it by filtering rather than set subtraction.

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.

1 participant