Doctest Failures: Expected [13.0, ...] Got [np.float64(13.0), ...]
in NumPy 2
Problem Statement
You run doctests successfully locally, but they fail in CI/CD environments (like GitHub Actions) for Python 3.9+ with errors like:
Expected:
[13.0, 12.0, 7.0]
Got:
[np.float64(13.0), np.float64(12.0), np.float64(7.0)]
The code results are correct, but NumPy 2.0+ represents scalar floats differently compared to NumPy 1.x. Doctests compare string outputs and fail due to this new representation.
Why This Happens
- NumPy 2.0 changed scalar representation:python
# NumPy 1.x: repr(np.array([13.0])[0]) → '13.0' # NumPy 2.x: repr(np.array([13.0])[0]) → 'np.float64(13.0)'
- Local tests pass because you may have NumPy 1.x installed. CI environments use newer Python versions that install NumPy 2.x by default.
Solution 1: Set NumPy Legacy Print Options (Recommended)
Add this to your test setup (e.g., conftest.py
, doctest preamble, or test runner initialization):
import numpy as np
np.set_printoptions(legacy='1.25')
Why it works:
This reverts NumPy's float representation to the pre-2.0 format globally. Your existing tests pass without modification.
Example with Doctest:
def example():
"""
>>> import numpy as np
>>> np.set_printoptions(legacy='1.25') # Add to failing modules
>>> [np.float64(13.0), np.float64(12.0)]
[13.0, 12.0]
"""
WARNING
Use legacy='1.25'
specifically. Other values won't fully revert the scalar representation.
Solution 2: Pin NumPy to Version 1.x
Add this to your requirements.txt
or CI setup:
numpy >= 1.26, == 1.*
Use this if:
- Your project isn’t compatible with NumPy 2.x yet.
- You prioritize quick fixes over migration.
Solution 3: Update Tests for NumPy 2 (Long-Term Fix)
Modify doctests to accept both representations using # doctest: +ELLIPSIS
:
def example():
"""
>>> arr = [np.float64(13.0), np.float64(12.0)] # doctest: +ELLIPSIS
>>> arr
[13.0, 12.0] # or [np.float64(13.0), ...] in NumPy 2
"""
Best practices:
- Prefer Solution 1 for minimal changes.
- Migrate to Solution 3 to future-proof tests against representation changes.
Key Takeaways
Approach | Effort Required | Compatibility |
---|---|---|
Set np.set_printoptions(legacy='1.25') | Add 1 line to test setup | Works with NumPy 1.x/2.x |
Pin NumPy to 1.* | Update dependency file | Locks you to NumPy 1.x |
Update doctests with ELLIPSIS | Modify every failing test | Works for all NumPy versions |
Choose Solution 1 to quickly resolve CI failures across Python 3.8–3.11. It ensures correctness while allowing you to upgrade to NumPy 2.x.