Skip to content

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.

Add this to your test setup (e.g., conftest.py, doctest preamble, or test runner initialization):

python
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:

python
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:

txt
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:

python
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:

  1. Prefer Solution 1 for minimal changes.
  2. Migrate to Solution 3 to future-proof tests against representation changes.

Key Takeaways

ApproachEffort RequiredCompatibility
Set np.set_printoptions(legacy='1.25')Add 1 line to test setupWorks with NumPy 1.x/2.x
Pin NumPy to 1.*Update dependency fileLocks you to NumPy 1.x
Update doctests with ELLIPSISModify every failing testWorks 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.