Release 2.1.3: ship the spectral fix, allow NumPy 2.x, test on 3.13/3.14 - #475
Merged
ThomasMBury merged 4 commits intoJul 28, 2026
Conversation
…est 3.13/3.14 Fixes ThomasMBury#474. compute_spectrum() raised KeyError 'key of type tuple not found and not a MultiIndex' on modern stacks: SciPy >=1.16 routes signal.welch through ShortTimeFFT, which slices its input as x[..., i0:i1]; given a pandas Series, pandas >=3.0 reads that tuple as a MultiIndex key and raises. The np.asarray() boundary fix has been on main since March but was never published, so every PyPI install still broke. Removes the numpy<2.0 ceiling -- NumPy 2.x works and is now under CI. The pin was what pushed users onto untested combinations. Dependency floors left alone deliberately: numpy>=1.26 already forces every other dep to be modern, so the stale 2018-era floors are inert, and changing them enlarges the diff for no user benefit. Extends CI to Python 3.13/3.14 with fail-fast:false -- nothing was testing a current stack, which is why a fix that worked was indistinguishable from a fix that had not shipped. Verified in clean containers with deps resolved from pyproject: py3.9.25 numpy 2.0.2 pandas 2.3.3 scipy 1.13.1 -> 30 passed 1 skipped, 6/6 spectral py3.12.13 numpy 2.5.1 pandas 3.0.3 scipy 1.18.0 -> 30 passed 1 skipped, 6/6 spectral py3.14.6 numpy 2.5.1 pandas 3.0.3 scipy 1.18.0 -> 30 passed 1 skipped, 6/6 spectral No API or behavioural changes. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Publishes to PyPI on a v* tag using PyPI Trusted Publishing (OIDC). No API token is stored anywhere: GitHub mints a short-lived identity token scoped to this workflow in this repository, and PyPI verifies it. Nothing long-lived exists to leak and a stolen credential cannot be replayed elsewhere. Guards the classic release failure: if the tag disagrees with the version in pyproject.toml the build fails loudly before publishing, rather than shipping under the wrong number or being rejected as a duplicate. Requires a one-time registration by a PyPI project Owner; the five values are in the file header. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…tags Verified every trigger path resolves correctly: tag -> PyPI; PR, push-to-main and the default manual dispatch -> build only; dispatch must explicitly name testpypi or pypi to publish anywhere. No event can publish by accident. Adds beyond the first draft: - builds on every PR, so a broken build or bad metadata surfaces at review time rather than at release time - twine check --strict, plus an install-and-import smoke test of the actual wheel - a TestPyPI dry-run target, so the whole path can be proven before touching real PyPI - concurrency guard against a double-pushed tag racing two uploads Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Found by executing the tutorials against the modern stack this PR enables. This PR relaxes the pin to allow NumPy 2.x. EntropyHub 2.0 -- the LATEST release, no fixed version exists -- still uses np.NaN in 4 files, removed in NumPy 2.0. So as it stood, 2.1.3 would have shipped a release where compute_entropy(method='sample') worked and method='kolmogorov' raised AttributeError. A partial break, which is worse than a total one: it stays hidden until someone uses that method. ewstools' own source is clean; the alias is restored immediately before the EntropyHub import. np.NaN was only ever a spelling of np.nan, so this is not a behaviour change. Verified on numpy 2.4.6 / pandas 3.0.5 / scipy 1.17.1: kolmogorov fails without the shim and passes with it; full suite 31 passed, 1 skipped. Should be removed once EntropyHub ships a NumPy 2 compatible release. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
Release prep for 2.1.3. Nothing in
ewstools/changes —git diff main..HEAD -- ewstools/is empty. The source is identical to what's onmaintoday; this only touches packaging, CI and the changelog.What's here
numpy>=1.26.0,<2.0→numpy>=1.26.0. The<2.0cap was precautionary rather than a real incompatibility, and NumPy 2.x is now covered by CI.fail-fast: falseso one red version doesn't mask the others. The TensorFlow install is skipped on 3.12–3.14 (TF <2.16 has no wheels there); the deep-learning tests skip themselves viapytest.importorskip, so the rest of the suite still runs.Why now
The
np.asarray()spectral fix (4e671ae) has been onmainsince April but has never gone out in a release, so 2.1.2 on PyPI still raisesKeyErroron everycompute_spectrum()call against a current SciPy/pandas. That's #474.The stale
<2.0pin compounds it: on Python 3.13/3.14 there is no NumPy 1.x wheel, so at the moment there's no clean way topip installa working ewstools on a current Python at all — users need a--no-depsinstall offmain, which is what I've posted as a stopgap on #474. Releasing 2.1.3 removes the need for that.Refs #474 — deliberately not "closes", since from a user's point of view the issue is resolved when 2.1.3 reaches PyPI, not when this merges.
Verification
Reproduced the #474 failure and confirmed this code fixes it, on NumPy 2.4.6 / pandas 3.0.5 / SciPy 1.17.1: released 2.1.2 raises the reported
KeyError, while this code runscompute_spectrum,compute_smaxandcompute_spec_typeclean and leaves NumPy 2.x in place.No rush on merging, and happy to change anything here. The PyPI upload is a separate step and won't happen until you've had a look.