pytest-dev/pytest · error · TypeError
pytest.approx() does not support nested data structures
Error message
pytest.approx() does not support nested data structures: {!r} at index {}
full sequence: {} What it means
ApproxSequenceLike.__init__ rejects any element whose type matches the expected sequence's own type (e.g. a list inside a list, a tuple inside a tuple). pytest's sequence approximation is intentionally single-level: it zips expected and actual element-by-element. Nested sequences would be ambiguous about how to apply tolerance, so they are rejected up front with the offending element, its index, and the full sequence pretty-printed.
Solutions
- Use a numpy array and approx(np.array(...)) for multi-dimensional numeric data.
- Compare each inner sequence separately: `for e, a in zip(expected, actual): assert a == approx(e)`.
- Convert the outer container so inner and outer are different sequence types (e.g. tuple of lists).
Example fix
# before assert actual == approx([[1.0, 2.0], [3.0, 4.0]]) # after import numpy as np assert np.array(actual) == approx(np.array([[1.0, 2.0], [3.0, 4.0]]))
Defensive patterns
Strategy: validation
Validate before calling
from collections.abc import Sequence
def is_flat_sequence(seq) -> bool:
seq_t = type(seq)
return all(not isinstance(x, seq_t) for x in seq)
# usage
if is_flat_sequence(expected):
assert actual == approx(expected)
else:
import numpy as np
assert np.array(actual) == approx(np.array(expected)) Type guard
from collections.abc import Sequence
def is_flat_numeric_sequence(obj) -> bool:
return (
isinstance(obj, Sequence)
and not isinstance(obj, (str, bytes))
and all(not isinstance(x, type(obj)) for x in obj)
) Prevention
- Use numpy arrays + approx() for multi-dimensional numeric data.
- Compare inner sequences individually in a loop.
- Mix sequence types (tuple of lists) only as an explicit workaround.
When it happens
Trigger: Calling approx([[1.0, 2.0], [3.0, 4.0]]), approx([(1.0, 2.0)]) where the element is the same sequence type, or approx on a custom Sequence subclass whose items are also that subclass. Triggered at ApproxSequenceLike.__init__ (src/_pytest/approx.py:360-363). Note: lists inside tuples or tuples inside lists are allowed because only same-type nesting is checked.
Common situations: Matrix/multi-dimensional data represented as nested lists; comparing batched numerical results; converting numpy arrays to nested lists for comparison.
Related errors
- pytest.approx() does not support nested dictionaries: key=
- absolute tolerance can't be NaN.
- absolute tolerance can't be negative
- absolute tolerance for a scalar value must be an int, float…
- approx() is not supported in a boolean context. Did you…
AI-assisted analysis of pytest-dev/pytest@0d6fbdeffa (2026-08-11).
Data as JSON: /api/errors/edcf92cb9d366e2a.
Report an issue: GitHub.
Appendix: 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 0d6fbdeffa)