Skip to content

Add Python 3.14 support#284

Merged
igerber merged 3 commits intomainfrom
python-3-14
Apr 7, 2026
Merged

Add Python 3.14 support#284
igerber merged 3 commits intomainfrom
python-3-14

Conversation

@igerber
Copy link
Copy Markdown
Owner

@igerber igerber commented Apr 7, 2026

Summary

  • Upgrade PyO3 from 0.22 to 0.28 and rust-numpy from 0.22 to 0.28 for Python 3.14 header compatibility
  • Bump ndarray from 0.16 to 0.17 (required by numpy 0.28)
  • Rename 14 to_pyarray_bound(py)to_pyarray(py) calls across 4 Rust source files (mechanical migration — code already used the modern Bound API)
  • Update requires-python from <3.14 to <3.15 and add 3.14 classifier
  • Add Python 3.14 to CI test matrix and all wheel build targets (Linux, macOS, Windows)
  • Update pure-Python fallback CI job to test on Python 3.14

Methodology references (required if estimator / math changes)

  • N/A — no methodology changes. All changes are Rust dependency upgrades, mechanical API renames, and CI/build configuration.

Validation

  • Tests added/updated: No new tests. Existing suite validates correctness:
    • test_rust_backend.py: 68/68 passed (Rust↔Python equivalence)
    • Full suite: 3198 passed, 0 failures
  • Backtest / simulation / notebook evidence: N/A

Security / privacy

  • Confirm no secrets/PII in this PR: Yes

Generated with Claude Code

…h matrices

Upgrade PyO3 from 0.22 to 0.28 and rust-numpy from 0.22 to 0.28 to enable
Python 3.14 compatibility. PyO3 0.22 cannot compile against 3.14 headers,
and since maturin is the build backend, pip install fails entirely without
this upgrade (the runtime fallback never gets a chance to activate).

The migration is mechanical: the code already uses the modern Bound<T> API,
so only 14 to_pyarray_bound→to_pyarray renames were needed. ndarray bumped
from 0.16 to 0.17 as required by numpy 0.28.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 7, 2026

Overall Assessment

✅ Looks good. No unmitigated P0/P1 findings. The Rust source edits are wrapper-level NumPy conversion migrations, not changes to estimator math, weighting, variance formulas, identification checks, or defaults; numpy 0.28 documents to_pyarray() as copying borrowed Rust data into a newly allocated NumPy array. (docs.rs)

Executive Summary

  • No P0/P1 issues found. The touched Rust paths are array-return wrappers in bootstrap, robust-vcov/OLS, SyntheticDiD/SDID weights, and TROP exports; I did not find any methodology drift relative to the registry.
  • The edge-case checklist is not materially engaged by this diff: no new inference formulas, NaN guards, control-group logic, or public parameter propagation paths were added.
  • P2: the PyO3/rust-numpy upgrade raises the Rust source-build floor to 1.83, but the crate still does not declare rust-version, so sdist/source-build failures will be later and less actionable than they need to be. (docs.rs)
  • P3: README.md:L2770-L2773 still says Python 3.9 - 3.13, which now conflicts with package metadata and CI.
  • The CI/publish expansion itself is coherent: the Linux manylinux images used here include cp314-cp314, so the new wheel loop target is valid. (github.com)

Methodology

No findings. I cross-checked the touched Rust-backed code paths in rust/src/bootstrap.rs:L17-L52, rust/src/linalg.rs:L16-L190, rust/src/weights.rs:L41-L57, rust/src/weights.rs:L624-L723, rust/src/trop.rs:L37-L47, rust/src/trop.rs:L1088-L1101, and rust/src/trop.rs:L1828-L1841 against docs/methodology/REGISTRY.md:L35-L83, docs/methodology/REGISTRY.md:L87-L214, docs/methodology/REGISTRY.md:L1190-L1315, and docs/methodology/REGISTRY.md:L1607-L1752. The diff only renames to_pyarray_bound(py) to to_pyarray(py), and rust-numpy 0.28 documents that API as the same borrowed-to-new-array copy operation. (docs.rs)

Code Quality

No findings. The mechanical migration appears complete in diff scope; I found no remaining to_pyarray_bound usage in the touched Rust sources, and the diff does not introduce any new inline inference/NaN-guard anti-patterns.

Performance

No findings. No hot-path algorithm, allocation strategy, or parallelization behavior changed beyond the same Rust-to-Python array handoff.

Maintainability

  • P2 Missing declared MSRV after the dependency bump in rust/Cargo.toml:L1-L42. Impact: this PR raises the effective Rust floor for source builds, but the crate still omits rust-version, while source builds remain part of the distribution story via publish.yml:L61-L62 and publish.yml:L122-L144. Users on older toolchains will get a later, less actionable failure. Concrete fix: add rust-version = "1.83" (or the minimum version you actually verify) to rust/Cargo.toml, and document that requirement anywhere sdist/source builds are described. (docs.rs)

Tech Debt

No findings. TODO.md does not already track the two non-blocking follow-ups above, but neither is a merge blocker.

Security

No findings. The diff adds no new secret material, credential handling, or untrusted-input surface.

Documentation/Tests

- Add rust-version = "1.83" to Cargo.toml (PyO3 0.28 MSRV) so source
  builds fail early with an actionable error on older toolchains
- Update README Requirements from "Python 3.9 - 3.13" to "3.9 - 3.14"

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@igerber
Copy link
Copy Markdown
Owner Author

igerber commented Apr 7, 2026

/ai-review

@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 7, 2026

🔁 AI review rerun (requested by @igerber)

Head SHA: e07b0c7f71f7c0f25d236249e24f9382672b479d


Overall Assessment

✅ Looks good

Review based on the provided diff and local source context; I did not execute builds/tests in this read-only environment.

Executive Summary

  • No unmitigated P0/P1 findings. The Rust source edits stay at the Python array-conversion boundary and do not alter estimator math, weighting, inference, identification checks, or defaults.
  • Re-review status: the prior stale-README issue is resolved, while the prior MSRV concern is only partially resolved.
  • One P2 maintainability issue remains in rust/Cargo.toml:L1-L38; details below.
  • The Python 3.14 metadata, README, CI, and wheel-matrix updates are otherwise internally consistent across pyproject.toml:L11-L42, README.md:L2770-L2775, publish.yml:L36-L45, publish.yml:L68-L105, and rust-test.yml:L76-L199.
  • I found no new edge-case or inference anti-patterns in the touched Rust files.

Methodology

Code Quality

  • No findings. The migration is mechanically consistent in diff scope, and I did not find new inline inference or partial-NaN-guard anti-patterns in the touched Rust files.

Performance

  • No findings. No hot-path algorithm, estimator-side allocation strategy, or parallelism setting changed beyond the existing Rust-to-Python return conversion boundary.

Maintainability

  • Severity: P2.
  • Impact: rust/Cargo.toml:L1-L38 now declares rust-version = "1.83", but the same manifest still depends on faer = "0.24". numpy 0.28.0 documents Rust 1.83 as its floor, while faer 0.24.0 documents Rust 1.84 as its MSRV, so the manifest currently advertises a lower Rust floor than the dependency set actually guarantees. Source builds on Rust 1.83 can therefore fail later in dependency resolution/compilation instead of being rejected up front. (docs.rs)
  • Concrete fix: Raise rust-version to 1.84, or pin/downgrade faer to a release you have verified on Rust 1.83 before claiming 1.83 support.

Tech Debt

  • No findings. TODO.md:L51-L94 does not already track the MSRV mismatch above, so that item remains an active P2 rather than a deferred/mitigated limitation.

Security

  • No findings. The diff does not add secrets, credential handling, shell injection surface, or new untrusted-input execution paths.

Documentation/Tests

faer 0.24 requires Rust 1.84, which is higher than PyO3 0.28's 1.83
floor. Declare the actual minimum so source builds fail early.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@igerber
Copy link
Copy Markdown
Owner Author

igerber commented Apr 7, 2026

/ai-review

@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 7, 2026

🔁 AI review rerun (requested by @igerber)

Head SHA: 30faedf4020727e7bca02b6453569c390492095e


Overall Assessment

✅ Looks good

Review based on the supplied unified diff and local source context. I did not execute builds/tests in this read-only environment.

Executive Summary

Methodology

Code Quality

  • No findings. Severity: none. Impact: the migration is mechanically consistent rather than partial; all touched Rust return conversions now use the same ToPyArray pattern, and I found no leftover _bound helper calls under rust/src. The touched TROP bootstrap paths also preserve the existing undefined-inference guard at rust/src/trop.rs:1087 and rust/src/trop.rs:1827. Concrete fix: none.

Performance

Maintainability

  • No findings. Severity: none. Impact: the previous re-review P2 is resolved because rust/Cargo.toml:5 now matches the dependency floor implied by rust/Cargo.toml:34. Concrete fix: none.

Tech Debt

  • No findings. Severity: none. Impact: I did not identify a new deferred item introduced by this PR, and TODO.md:51 does not contain a relevant tracked limitation that would mask a correctness issue here. Concrete fix: none.

Security

  • No findings. Severity: none. Impact: the diff only updates dependency versions, CI/build matrices, packaging metadata, and Rust-to-Python array return helpers; it does not add new secret handling, subprocess construction, or untrusted-input execution paths. Concrete fix: none.

Documentation/Tests

@igerber igerber added the ready-for-ci Triggers CI test workflows label Apr 7, 2026
@igerber igerber merged commit 279f110 into main Apr 7, 2026
24 of 26 checks passed
@igerber igerber deleted the python-3-14 branch April 7, 2026 23:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-for-ci Triggers CI test workflows

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant