pytest-dev/pytest · error · TypeError

pytest.approx() does not support nested data structures: {!r

Error message

pytest.approx() does not support nested data structures: {!r} at index {}
  full sequence: {}

What it means

pytest.approx() does not support nested sequences (lists/tuples within lists). When ApproxSequenceLike.__init__ iterates the expected sequence, if any element is itself an instance of the same sequence type, pytest raises TypeError. approx() only compares flat sequences of numbers.

Source

Thrown at src/_pytest/approx.py:363

            yield actual[k], self.expected[k]


class ApproxSequenceLike(Approx[Sequence[Any]]):
    """Perform approximate comparisons where the expected value is a sequence of numbers."""

    def __init__(
        self,
        expected: Sequence[Any],
        rel: float | Decimal | timedelta | None,
        abs: float | Decimal | timedelta | None,
        nan_ok: bool,
    ) -> None:
        __tracebackhide__ = True

        for index, x in enumerate(expected):
            if isinstance(x, type(expected)):
                msg = "pytest.approx() does not support nested data structures: {!r} at index {}\n  full sequence: {}"
                raise TypeError(msg.format(x, index, pprint.pformat(expected)))

        super().__init__(expected, rel=rel, abs=abs, nan_ok=nan_ok)

    def __repr__(self) -> str:
        seq_type = type(self.expected)
        if seq_type not in (tuple, list):
            seq_type = list
        return f"approx({seq_type(self._approx_scalar(x) for x in self.expected)!r})"

    def _repr_compare(self, other_side: Sequence[float]) -> list[str]:
        import math

        if len(self.expected) != len(other_side):
            return [
                "Impossible to compare lists with different sizes.",
                f"Lengths: {len(self.expected)} and {len(other_side)}",
            ]

View on GitHub (pinned to 98b357f69e)

Solutions

  1. Use numpy arrays with approx for multi-dimensional data: assert np.array_equal(actual, approx(expected_array)).
  2. Compare each sub-sequence individually with a loop.
  3. Flatten the nested structure if the comparison is semantically flat.

Example fix

# before
assert result == approx([[1.0, 2.0], [3.0, 4.0]])

# after
import numpy as np
assert np.allclose(result, [[1.0, 2.0], [3.0, 4.0]])
Defensive patterns

Strategy: type-guard

Validate before calling

from collections.abc import Sequence

def is_flat_numeric_sequence(seq: Sequence) -> bool:
    """Check that a sequence contains no nested sequences (suitable for approx())."""
    return all(not isinstance(x, type(seq)) for x in seq)

# usage:
# assert is_flat_numeric_sequence(expected), 'approx() requires a flat list; use numpy for 2D data'

Type guard

from collections.abc import Sequence

def is_approx_compatible_sequence(value) -> bool:
    return isinstance(value, Sequence) and not isinstance(value, (str, bytes)) and all(
        not isinstance(x, type(value)) for x in value
    )

Prevention

When it happens

Trigger: Calling approx([[1.0, 2.0], [3.0, 4.0]]). The element [1.0, 2.0] is a list, isinstance(x, type(expected)) is True, so TypeError is raised.

Common situations: Comparing 2D matrices, batches of results, or nested arrays where the developer expects element-wise tolerance comparison at all depths.

Related errors


AI-assisted analysis of pytest-dev/pytest@98b357f69e (2026-08-04). Data as JSON: /data/errors/edcf92cb9d366e2a.json. Report an issue: GitHub.