Support Python 3.11–3.14 and NumPy 2#161
Open
pscicluna wants to merge 2 commits into
Open
Conversation
Fixes installation on modern Python (Starfish-develop#160): - Migrate packaging metadata from setup.py to PEP 621 pyproject.toml with requires-python >=3.11 (was capped at <3.11) - Drop the obsolete dataclasses backport and the abandoned nptyping dependency (replaced by numpy.typing.NDArray annotations) - Relax dependency upper caps (astropy, numpy, scipy, scikit-learn, extinction, h5py, flatdict, toml, tqdm) so modern wheels are used - Replace np.trapz with scipy.integrate.trapezoid and np.Inf with np.inf for NumPy 2 compatibility (works with NumPy 1.24+ too) - Replace eval() with getattr() for extinction law lookup - Fix matplotlib "seaborn" style name removed in matplotlib 3.6 - Remove dead "samplers" entry from Starfish.__all__ - Update CI matrix to 3.11-3.14, bump stale GitHub Action versions, drop unmaintained pytest-black, build releases with python -m build - Fix Sphinx 4+ add_css_file API in docs/conf.py, unpin docs toolchain, migrate .readthedocs.yml to the current schema Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W1cwqRt8tE5LDgfxmipTBk
np.asarray() on the PHOENIX grid's ragged points list (58 Teff, 12 logg, 9 Z values) raises ValueError on numpy>=1.24; iterate the list directly instead. Also raw-string two matplotlib labels that trigger SyntaxWarning on Python 3.14. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W1cwqRt8tE5LDgfxmipTBk
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Support Python 3.11–3.14 and NumPy 2
I'm not entirely sure if Starfish is still alive or if it is now abandonware, but I find it useful and I'm not really aware of a good alternative, so I thought I would take a shot at updating some of the key infrastructure for it. This is primarily intended to fix issue #160, and in doing so it seemed logical to make a few other updates to modernise the package. The updates were written by Claude, but are fairly simple - I've reviewed it all and can't see any obvious problems, and would welcome a thorough review. Claude's own summary of the changes is below.
Problem
Starfish currently cannot be installed on any Python newer than 3.10:
python_requires = ">=3.7,<3.11"makes pip reject the package outright on 3.11+(
ERROR: Package 'astrostarfish' requires a different Python: 3.11.5 not in '<3.11,>=3.7').astropy>=4,<6,numpy<2, …) force pip tobuild very old sdists from source, which fails against modern build tooling (e.g. the
astropy 4.x
ImportError: cannot import name 'soft_unicode' from 'markupsafe'reportedin Installation problems through pip #160).
nptyping==1.*(abandoned; incompatible withNumPy 2 and the source of the
<3.11cap) and thedataclassesPyPI backport (onlyever needed on Python 3.6, and harmful on modern interpreters).
Since Starfish is pure Python, unblocking modern interpreters is almost entirely a
packaging/metadata fix plus a handful of small code changes.
Changes
Packaging
setup.pyto a PEP 621pyproject.toml;requires-python = ">=3.11", classifiers for 3.11–3.14.dataclassesbackport andnptyping.astropy>=5.3,numpy>=1.24(NumPy 1.x and2.x are both supported),
scipy>=1.10,scikit-learn>=1.2,extinction>=0.4.7(ships wheels through cp314),
h5py>=3.8,flatdict>=4.0,toml>=0.10.2,tqdm>=4.60.tomlis kept (rather than stdlibtomllib) becauseSpectrumModel.save()relies ontoml.TomlNumpyEncoderfor writing NumPy scalars, andtomllibis read-only.Code compatibility
numpy.typing.NDArray(
spectrum.py,emulator/emulator.py,models/utils.py) — annotation-only.np.trapz→scipy.integrate.trapezoid(7 sites; same algorithm, works onNumPy 1.24–2.x) and
np.Inf→np.inf(removed in NumPy 2).eval("extinction.{law}")→getattr(extinction, law)(law names were alreadywhitelist-validated).
plt.style.use("seaborn")→"seaborn-v0_8"with a graceful fallback (the bare namewas removed in matplotlib 3.6, so importing
emulator.plottingraised).SyntaxWarning: invalid escape sequence '\l'on Python 3.12+ (an error in a future Python)."samplers"entry fromStarfish.__all__(no such module).test_no_par_truncation, which callednp.asarray()on the PHOENIX grid'sragged parameter list — an error since NumPy 1.24. The test now iterates the list
directly (equivalent to the old object-array behaviour).
CI / docs
actions (
checkout@v4,setup-python@v5,cache@v4,codecov@v4); dropped theunmaintained
pytest-blackplugin from the test run.python -m buildandpypa/gh-action-pypi-publish@release/v1(replaces the deprecatedpep517.build).app.add_stylesheet→app.add_css_file(removed in Sphinx 4), unpinned thedocs toolchain (builds cleanly on Sphinx 9.1), migrated
.readthedocs.ymlto thecurrent
build.os/build.toolsschema.Correctness and performance
No numerical code path changes behaviour: the annotation swap has zero runtime effect,
scipy.integrate.trapezoidis the implementation NumPy's own migration notes point to,and
np.Inf/np.infare the same object.Verified explicitly by running the old code + old pinned deps (Python 3.10 / NumPy 1.26)
against the new code (Python 3.13 / NumPy 2.5) on identical inputs across 13 outputs
(all transforms, all five extinction laws, PHOENIX flux normalization): the
trapezoid-affected paths are bit-for-bit identical; the remainder agree to≤ 7×10⁻¹³ relative (FFT differences between NumPy builds, not this diff). The
pytest-benchmark suite shows performance parity.
Testing
ubuntu / macos / windows — against real downloaded PHOENIX models:
https://github.com/pscicluna/Starfish/actions/runs/29474810935
with identical results, confirming the change is NumPy-1/2 agnostic.
python -m build+twine checkpass; cleanpip installverified from both wheeland sdist on 3.11–3.14.
🤖 Generated with Claude Code