Skip to content

refactor(core): consistent names and public homes for hmf.core APIs - #422

Open
steven-murray wants to merge 1 commit into
mainfrom
refactor/core-naming-visibility
Open

steven-murray wants to merge 1 commit into
mainfrom
refactor/core-naming-visibility

Conversation

@steven-murray

@steven-murray steven-murray commented Oct 8, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Renames and visibility changes in hmf.core (the experimental v4 preview). The maintainer approved them. There are no deprecation aliases, and numbers come out identical. This PR changes no v3 code.

Renames (old → new)

Old New
Transfer.power_kernel(species) Transfer.power_source(species). It returns a PowerSource, not an array. UnnormalisedPower.power_kernel(k) keeps its name because it is a real plain-array kernel.
hmf.core._species hmf.core.species
Filter.window_derivatives (and TopHat/SharpK/SmoothK) Filter.window_derivatives_kernel

Visibility changes

  • hmf.core.species is public. It has a numpydoc module docstring with an example. docs/api_core.rst lists it under Conventions, the "Shared helpers (internal)" section is removed, and docs/core.rst links to it.
  • One home for the species constants. transfer_models and _boltzmann import from species and no longer list MATTER_SPECIES or Species in __all__. A test enforces this.
  • The fits' _parameters stay private. Nothing outside fits.py calls them; each fit's own _fsigma is the only caller. Their docstrings no longer say "for library code".
  • BBKS.shape_parameter returns a scalar Quantity in h_Mpc through unit_boundary(returns=h_Mpc). solve() uses the plain-float _shape_parameter.
  • import hmf.core imports every public module and lists it in __all__. The newly added ones are cache, growth, growth_models, species, transfer and transfer_models, so import hmf.core; hmf.core.transfer now works.
    • growth.py annotates with qualified names (hmf.core.transfer.Transfer), which keeps the docs cross-reference unambiguous next to the v3 Transfer. attrs resolves those annotations while the class is being created, which now happens during the package import. So hmf/core/__init__.py binds hmf.core on hmf before it imports the submodules. growth.py itself is unchanged.
    • import hmf still doesn't import hmf.core. hmf.core imports no CAMB or CLASS module at module level. Importing it takes about 0.25 s on top of import hmf. CAMB still shows up in sys.modules, but v3's import hmf loads it.

Open point (not changed here)

Filter.window_derivatives_kernel now follows the naming convention. It does not check its input against valid_domain; window and dwindow_dlnx do that check. Adding the check would change behaviour on MassVariance's hot path, which this PR avoids. It isn't flagged by test_every_public_kernel_has_an_out_of_domain_case either, because that test doesn't scan filters. I'd fix both in a follow-up if you want the convention enforced there.

Type of change

  • Maintenance (refactoring, CI, dependencies, etc.)

Checklist

I have

  • Added or updated tests covering this change:
    • a new shape_parameter test (Γ = Ω_m0·h with no baryons, the Sugiyama forms agree at h = 0.5, unit and scalar checks);
    • init tests in a fresh interpreter (every public module is imported and in __all__);
    • a check that the species constants are not re-exported;
    • updated callers in the tests and benchmarks.
  • Updated docstrings and/or docs where relevant.

Local checks:

  • prek on the changed files passes.
  • uv run mypy (strict) passes.
  • tests/core + tests/regression: 1791 passed, 13 skipped.
  • benchmarks/test_gates.py: 18 passed.
  • The docs build with -W passes.

🤖 Generated with Claude Code

https://claude.ai/code/session_016tGMit4S1Xx7EoWNBYHZsF


Generated by Claude Code

Summary by Sourcery

Align the experimental hmf.core API with consistent public naming, module visibility, and unit behavior.

Enhancements:

  • Standardize the experimental core API names and make species helpers a documented public module.
  • Expose all public core modules through hmf.core and keep shared species constants in their single public home.
  • Return BBKS shape parameters as scalar quantities with explicit units while retaining internal float calculations.

Documentation:

  • Update core API documentation and references for the renamed public modules and methods.

Tests:

  • Update and expand core, regression, and benchmark coverage for the renamed APIs, module exports, species ownership, and BBKS units.

Chores:

  • Keep fit parameter helpers private and remove the old API names without deprecation aliases.

- Transfer.power_kernel(species) -> Transfer.power_source(species): it returns
  a PowerSource. UnnormalisedPower.power_kernel(k) keeps its name.
- hmf.core._species -> hmf.core.species, a public module with a numpydoc
  module docstring, listed with the conventions in docs/api_core.rst. It is
  the one home of the species constants: transfer_models and _boltzmann no
  longer list MATTER_SPECIES / Species in __all__.
- Filter.window_derivatives -> Filter.window_derivatives_kernel (all filters).
- The fits' private _parameters stay private (only their own _fsigma calls
  them); their docstrings no longer promise library use.
- BBKS.shape_parameter returns a Quantity in h/Mpc through unit_boundary;
  solve() uses the plain-float _shape_parameter.
- import hmf.core imports and lists every public module (cache, growth,
  growth_models, species, transfer, transfer_models added). hmf.core is bound
  on hmf before the submodules import, so growth's qualified annotations
  resolve during package import. import hmf still does not import hmf.core.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016tGMit4S1Xx7EoWNBYHZsF
@steven-murray steven-murray added the type: maint: refactoring Refactoring label Oct 8, 2026 — with Claude
@sourcery-ai

sourcery-ai Bot commented Oct 8, 2026

Copy link
Copy Markdown

Sorry @steven-murray, you've used your own review budget of 250,000 diff characters for the last 7 days.

You can request another review in 2 days and 17 hours by commenting @sourcery-ai review. Upgrade to get a review now.

@sourcery-ai

sourcery-ai Bot commented Oct 8, 2026

Copy link
Copy Markdown

Reviewer's Guide

This refactor standardizes v4 core API names, establishes hmf.core.species and complete public-module imports as the canonical public surfaces, adds a unit-aware BBKS shape-parameter boundary, and updates all implementation, documentation, benchmark, and regression references without changing v3 code or numerical results.

Sequence diagram for unit-aware BBKS shape parameter

sequenceDiagram
    participant Caller
    participant BBKS
    participant UnitBoundary
    participant Solve
    Caller->>BBKS: shape_parameter(cosmology)
    BBKS->>BBKS: _shape_parameter(cosmology)
    BBKS-->>UnitBoundary: return float Gamma
    UnitBoundary-->>Caller: return Quantity in h_Mpc
    Solve->>BBKS: _shape_parameter(cosmology)
    BBKS-->>Solve: return plain float Gamma
Loading

File-Level Changes

Change Details Files
Renamed the public transfer and filter kernel APIs and updated dependent code, documentation, tests, and benchmarks.
  • Renamed Transfer.power_kernel to power_source while preserving UnnormalisedPower.power_kernel.
  • Renamed Filter.window_derivatives to window_derivatives_kernel across the base class and filter implementations.
  • Updated MassVariance, warning messages, references, tests, and benchmark callers for the new names.
src/hmf/core/transfer.py
src/hmf/core/filters.py
src/hmf/core/mass_variance.py
src/hmf/core/power_source.py
benchmarks/test_gates.py
tests/core/test_core_boltzmann.py
tests/core/test_core_filters.py
tests/core/test_core_kernel_safety.py
tests/core/test_core_power_source.py
tests/core/test_core_transfer.py
Promoted species helpers to a single public module and removed their re-exports from consuming modules.
  • Renamed _species.py to species.py and added public documentation and examples.
  • Changed internal imports and documentation references to hmf.core.species.
  • Removed species constants and types from transfer_models and _boltzmann public exports, with tests enforcing the single public home.
src/hmf/core/species.py
src/hmf/core/_boltzmann.py
src/hmf/core/growth_models.py
src/hmf/core/transfer.py
src/hmf/core/transfer_models.py
src/hmf/core/fits.py
docs/api_core.rst
docs/core.rst
tests/core/test_core_shared_helpers.py
tests/core/test_core_fits.py
tests/core/test_core_power_source.py
tests/regression/v4_providers.py
Made all public core modules available from import hmf.core and handled qualified annotation resolution during package initialization.
  • Imported newly public modules and added them to hmf.core.__all__.
  • Bound hmf.core on the parent package before importing submodules so qualified annotations in growth resolve during class creation.
  • Added a fresh-interpreter test verifying every non-private package module is imported, exposed, and listed.
src/hmf/core/__init__.py
tests/core/test_core_init.py
Added a unit-aware public BBKS shape-parameter API while retaining a plain-float internal path for solving transfer models.
  • Decorated shape_parameter to return a scalar Quantity in h_Mpc.
  • Moved the numerical implementation to private _shape_parameter and updated solve() to use it.
  • Added coverage for units, scalar output, baryon corrections, and equivalent Sugiyama forms.
src/hmf/core/transfer_models.py
tests/core/test_core_transfer.py
Clarified the private status and intended callers of fit parameter helpers.
  • Updated _parameters docstrings to describe their fit-local _fsigma usage rather than general library use.
src/hmf/core/fits.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@github-actions github-actions Bot added the type: maint: documentation Improvements or additions to documentation label Oct 8, 2026
@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

🐰 Bencher Report

Projecthmf
Branchrefactor/core-naming-visibility
Testbedubuntu-latest
Click to view all benchmark results
BenchmarkLatencyBenchmark Result
microseconds (µs)
(Result Δ%)
Upper Boundary
microseconds (µs)
(Limit %)
benchmarks/test_construction.py::test_default_cached_dndm📈 view plot
🚷 view threshold
1.66 µs
(-32.99%)Baseline: 2.48 µs
4.21 µs
(39.38%)
benchmarks/test_construction.py::test_default_construct📈 view plot
🚷 view threshold
322,641.05 µs
(-33.66%)Baseline: 486,328.02 µs
800,777.43 µs
(40.29%)
benchmarks/test_construction.py::test_default_construct_and_dndm📈 view plot
🚷 view threshold
333,801.92 µs
(-31.32%)Baseline: 486,028.86 µs
797,927.36 µs
(41.83%)
benchmarks/test_construction.py::test_default_first_dndm📈 view plot
🚷 view threshold
64.08 µs
(-31.38%)Baseline: 93.38 µs
144.29 µs
(44.41%)
benchmarks/test_construction.py::test_eh_construct_and_dndm📈 view plot
🚷 view threshold
35,846.73 µs
(-42.77%)Baseline: 62,636.66 µs
119,449.24 µs
(30.01%)
benchmarks/test_construction.py::test_get_hmf_z📈 view plot
🚷 view threshold
373,009.06 µs
(-34.09%)Baseline: 565,962.68 µs
935,879.67 µs
(39.86%)
benchmarks/test_construction.py::test_import[import_hmf]📈 view plot
🚷 view threshold
786,582.85 µs
(-29.03%)Baseline: 1,108,302.49 µs
1,701,255.43 µs
(46.24%)
benchmarks/test_construction.py::test_import[python]📈 view plot
🚷 view threshold
13,661.41 µs
(-17.84%)Baseline: 16,628.41 µs
24,878.02 µs
(54.91%)
benchmarks/test_construction.py::test_introspection[get_all_parameter_defaults]📈 view plot
🚷 view threshold
373.73 µs
(-28.14%)Baseline: 520.07 µs
852.15 µs
(43.86%)
benchmarks/test_construction.py::test_introspection[get_all_parameter_names]📈 view plot
🚷 view threshold
190.15 µs
(-34.32%)Baseline: 289.52 µs
477.80 µs
(39.80%)
benchmarks/test_construction.py::test_introspection[parameter_info]📈 view plot
🚷 view threshold
284.18 µs
(-30.76%)Baseline: 410.44 µs
670.75 µs
(42.37%)
benchmarks/test_construction.py::test_introspection[quantities_available]📈 view plot
🚷 view threshold
356.55 µs
(-34.61%)Baseline: 545.31 µs
913.63 µs
(39.03%)
benchmarks/test_core_units.py::test_unit_boundary_overhead[canonical]📈 view plot
🚷 view threshold
9,398.00 µs
(-32.76%)Baseline: 13,977.53 µs
24,664.86 µs
(38.10%)
benchmarks/test_core_units.py::test_unit_boundary_overhead[physical]📈 view plot
🚷 view threshold
20,390.62 µs
(-36.00%)Baseline: 31,859.34 µs
55,552.47 µs
(36.71%)
benchmarks/test_core_units.py::test_unit_boundary_overhead[undecorated]📈 view plot
🚷 view threshold
335.02 µs
(-40.25%)Baseline: 560.70 µs
996.83 µs
(33.61%)
benchmarks/test_derived.py::test_halofit_after_z_change📈 view plot
🚷 view threshold
535.41 µs
(-51.53%)Baseline: 1,104.70 µs
2,144.24 µs
(24.97%)
benchmarks/test_derived.py::test_halofit_first📈 view plot
🚷 view threshold
769.22 µs
(-39.65%)Baseline: 1,274.63 µs
2,235.46 µs
(34.41%)
benchmarks/test_derived.py::test_mass_conversion_first📈 view plot
🚷 view threshold
62,107.70 µs
(-43.49%)Baseline: 109,905.12 µs
207,141.34 µs
(29.98%)
benchmarks/test_derived.py::test_mass_conversion_z_loop📈 view plot
🚷 view threshold
310,980.11 µs
(-43.86%)Baseline: 553,950.73 µs
1,041,016.03 µs
(29.87%)
benchmarks/test_scans.py::test_fit_scan📈 view plot
🚷 view threshold
3,975.03 µs
(-45.69%)Baseline: 7,319.24 µs
13,285.98 µs
(29.92%)
benchmarks/test_scans.py::test_n_scan📈 view plot
🚷 view threshold
87,989.44 µs
(-41.36%)Baseline: 150,062.91 µs
271,219.68 µs
(32.44%)
benchmarks/test_scans.py::test_sigma8_scan📈 view plot
🚷 view threshold
5,020.38 µs
(-47.14%)Baseline: 9,496.81 µs
17,562.00 µs
(28.59%)
benchmarks/test_scans.py::test_wdm_z_loop📈 view plot
🚷 view threshold
7,041.16 µs
(-48.58%)Baseline: 13,694.08 µs
25,414.10 µs
(27.71%)
benchmarks/test_scans.py::test_z_loop_dndm📈 view plot
🚷 view threshold
7,101.86 µs
(-46.76%)Baseline: 13,338.91 µs
24,917.57 µs
(28.50%)
benchmarks/test_scans.py::test_z_loop_ngtm📈 view plot
🚷 view threshold
23,483.80 µs
(-46.37%)Baseline: 43,786.74 µs
76,852.63 µs
(30.56%)
🐰 View full continuous benchmarking report in Bencher

@codecov

codecov Bot commented Oct 8, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.57%. Comparing base (e49c47b) to head (086090a).

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #422   +/-   ##
=======================================
  Coverage   99.57%   99.57%           
=======================================
  Files          59       59           
  Lines        7210     7215    +5     
=======================================
+ Hits         7179     7184    +5     
  Misses         31       31           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type: maint: documentation Improvements or additions to documentation type: maint: refactoring Refactoring

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants