Conversation
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
src/anndata/extensions.py (1)
1-70: Public re-export module matches the PR objective; examples are clear.
One consideration: importinganndata.extensionswill eagerly importanndata._repr; if import-time becomes a concern, consider lazy re-exports (module__getattr__) later.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
src/anndata/_repr/__init__.py(4 hunks)src/anndata/extensions.py(1 hunks)tests/test_repr_html.py(12 hunks)tests/visual_inspect_repr_html.py(3 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
tests/test_repr_html.py (1)
src/anndata/_repr/registry.py (3)
FormatterContext(102-141)SectionFormatter(202-277)TypeFormatter(144-199)
src/anndata/extensions.py (2)
src/anndata/_core/extensions.py (1)
register_anndata_namespace(146-237)src/anndata/_repr/registry.py (8)
FormattedEntry(88-98)FormattedOutput(56-84)FormatterContext(102-141)FormatterRegistry(339-417)SectionFormatter(202-277)TypeFormatter(144-199)register_formatter(523-551)extract_uns_type_hint(432-520)
🪛 Ruff (0.14.8)
src/anndata/extensions.py
95-110: __all__ is not sorted
Apply an isort-style sorting to __all__
(RUF022)
🔇 Additional comments (10)
src/anndata/_repr/__init__.py (3)
13-24: Doc note correctly steers users to the new public extension API.
This aligns the docs with the PR goal without affecting runtime behavior.
39-62: Example import paths updated toanndata.extensions(good).
Keeps the extensibility guidance on the supported public surface.
99-105: SectionFormatter example updated to public imports (good).tests/visual_inspect_repr_html.py (3)
24-29: Import migration toanndata.extensionsis consistent with the new public API.
43-49: Optional-dependency block correctly imports extension symbols from the public module.
241-247: MuData block uses the public extension import surface (good).tests/test_repr_html.py (4)
692-693: LGTM: tests now consume the publicformatter_registryexport.
699-705: LGTM: registry/type context symbols imported fromanndata.extensions.
742-743: LGTM: public imports used for fallback behavior test.
1707-1713: LGTM: type-hint formatter test now uses the public extension API.
src/anndata/extensions.py
Outdated
| __all__ = [ | ||
| # Accessor registration | ||
| "register_anndata_namespace", | ||
| # HTML formatter registration | ||
| "register_formatter", | ||
| "TypeFormatter", | ||
| "SectionFormatter", | ||
| "FormattedOutput", | ||
| "FormattedEntry", | ||
| "FormatterContext", | ||
| "FormatterRegistry", | ||
| "formatter_registry", | ||
| # Type hint utilities | ||
| "extract_uns_type_hint", | ||
| "UNS_TYPE_HINT_KEY", | ||
| ] |
There was a problem hiding this comment.
Fix Ruff RUF022 on __all__ (either sort, or explicitly ignore).
Given other modules intentionally group exports by category, adding the same # noqa: RUF022 pattern here seems simplest.
-__all__ = [
+__all__ = [ # noqa: RUF022 # organized by category, not alphabetically
# Accessor registration
"register_anndata_namespace",
# HTML formatter registration
"register_formatter",
"TypeFormatter",
"SectionFormatter",
"FormattedOutput",
"FormattedEntry",
"FormatterContext",
"FormatterRegistry",
"formatter_registry",
# Type hint utilities
"extract_uns_type_hint",
"UNS_TYPE_HINT_KEY",
]📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| __all__ = [ | |
| # Accessor registration | |
| "register_anndata_namespace", | |
| # HTML formatter registration | |
| "register_formatter", | |
| "TypeFormatter", | |
| "SectionFormatter", | |
| "FormattedOutput", | |
| "FormattedEntry", | |
| "FormatterContext", | |
| "FormatterRegistry", | |
| "formatter_registry", | |
| # Type hint utilities | |
| "extract_uns_type_hint", | |
| "UNS_TYPE_HINT_KEY", | |
| ] | |
| __all__ = [ # noqa: RUF022 # organized by category, not alphabetically | |
| # Accessor registration | |
| "register_anndata_namespace", | |
| # HTML formatter registration | |
| "register_formatter", | |
| "TypeFormatter", | |
| "SectionFormatter", | |
| "FormattedOutput", | |
| "FormattedEntry", | |
| "FormatterContext", | |
| "FormatterRegistry", | |
| "formatter_registry", | |
| # Type hint utilities | |
| "extract_uns_type_hint", | |
| "UNS_TYPE_HINT_KEY", | |
| ] |
🧰 Tools
🪛 Ruff (0.14.8)
95-110: __all__ is not sorted
Apply an isort-style sorting to __all__
(RUF022)
🤖 Prompt for AI Agents
In src/anndata/extensions.py around lines 95 to 110, the grouped __all__ export
list triggers Ruff RUF022 (unsorted __all__); to silence it without reordering,
append an explicit noqa for RUF022 to the __all__ assignment (e.g. add "# noqa:
RUF022" on the __all__ line or the closing bracket line) so the linter ignores
the unsorted export list while preserving the intentional grouping.
Add
anndata.extensionsmodule for unified extension APIThis PR extends scverse#2236 by adding a public
anndata.extensionsmodule that consolidates extension points for external packages.Live demo: Visual test page (Test 20 shows the unified accessor + section pattern)
Motivation
With the HTML repr system (scverse#2236) introducing
register_formatter,TypeFormatter, andSectionFormatter, and the recent addition ofregister_anndata_namespace(scverse#1870), anndata now has multiple extension mechanisms. However, they're scattered across different locations:anndata.register_anndata_namespaceanndata._repr.*anndata._io.specs._REGISTRYThis follows patterns established by pandas (
pd.api.extensions) and xarray for providing a stable extension API.Changes
New
anndata/extensions.pymodule that re-exports:register_anndata_namespace(accessors)register_formatter,TypeFormatter,SectionFormatter(HTML formatters)FormattedOutput,FormattedEntry,FormatterContextformatter_registryextract_uns_type_hint,UNS_TYPE_HINT_KEYUnified accessor + section visualization: Accessors can define a
_repr_section_method to automatically get a section in the HTML repr - no separateSectionFormatterregistration neededUpdated tests and examples to import from
anndata.extensionsUpdated docstrings to point users to the public API
Usage
Unified accessor with visualization (new!):
Separate formatter registration (still supported):
Future direction: Unified extension ecosystem
This aligns with the anndata roadmap (scverse#448) and ongoing discussions about extensibility. anndata already has an internal
IORegistry(anndata._io.specs.registry) that handles serialization registration withregister_readandregister_writemethods. Making this public would complete the extension story:This would address:
pd.api.extensions) and xarray for stable extension APIsThe existing
IORegistryinfrastructure is already well-designed with support for:register_write(dest_type, src_type, spec))IOSpec("dataframe", "0.2.0"))Exposing it through
anndata.extensionswould provide a stable public API without changing the internal implementation.Visual Test
The visual test page includes 20 test cases demonstrating various features. Test 20 specifically shows the unified accessor + section pattern with a
spatial_demoaccessor.Source: repr_html_visual_test.html gist
Checklist