pytest-dev/pytest · error · TypeError
pytest.approx() only supports ordered sequences, but got: {e
Error message
pytest.approx() only supports ordered sequences, but got: {expected!r} What it means
The approx() dispatcher accepts Decimal, Mapping, numpy array, sequence-like objects, datetime/timedelta, and scalars — but a Collection that is NOT ordered (no __getitem__) is unsupported. The classic case is a set. pytest refuses because element order is required to pair up actual vs expected values.
Source
Thrown at src/_pytest/approx.py:967
# The actual logic for making approximate comparisons can be found in
# ApproxScalar, which is used to compare individual numbers. All of the
# other Approx classes eventually delegate to this class. The ApproxBase
# class provides some convenient methods and overloads, but isn't really
# essential.
__tracebackhide__ = True
if isinstance(expected, Decimal):
return ApproxDecimal(expected, rel=rel, abs=abs, nan_ok=nan_ok) # type: ignore[return-value]
elif isinstance(expected, Mapping):
return ApproxMapping(expected, rel=rel, abs=abs, nan_ok=nan_ok) # type: ignore[return-value]
elif (np_array := _as_numpy_array(expected)) is not None:
return ApproxNumpy(np_array, rel=rel, abs=abs, nan_ok=nan_ok)
elif _is_sequence_like(expected):
return ApproxSequenceLike(expected, rel=rel, abs=abs, nan_ok=nan_ok) # type: ignore[return-value]
elif isinstance(expected, Collection) and not isinstance(expected, str | bytes):
msg = f"pytest.approx() only supports ordered sequences, but got: {expected!r}"
raise TypeError(msg)
elif isinstance(expected, (datetime, timedelta)):
return ApproxTimedelta(expected, rel=rel, abs=abs, nan_ok=nan_ok) # type: ignore[return-value]
else:
return ApproxScalar(expected, rel=rel, abs=abs, nan_ok=nan_ok)
def _is_sequence_like(expected: object) -> TypeGuard[Sequence[Any]]:
return (
hasattr(expected, "__getitem__")
and isinstance(expected, Sized)
and not isinstance(expected, str | bytes)
)
def _as_numpy_array(obj: object) -> ndarray | None:
"""
Return an ndarray if the given object is implicitly convertible to ndarray,
and numpy is already imported, otherwise None.View on GitHub (pinned to 98b357f69e)
Solutions
- Convert to an ordered structure: approx([1, 2, 3]) (list) or approx((1,2,3)) (tuple).
- If you want set-like membership, write the assertion explicitly: assert set(actual) == set(expected).
- For custom containers, implement __getitem__ and Sized or pass an iterable wrapped in list().
Example fix
// before
assert actual == approx({1, 2, 3})
// after
assert actual == approx([1, 2, 3]) Defensive patterns
Strategy: type-guard
Validate before calling
from collections.abc import Collection, Sequence
def approx_seq(expected):
if isinstance(expected, Collection) and not isinstance(expected, str | bytes | Sequence):
# unordered collection (e.g. set) — sort or convert before approx
expected = sorted(expected)
return pytest.approx(expected) Type guard
from collections.abc import Sequence
def is_ordered_sequence(v) -> bool:
return isinstance(v, Sequence) and not isinstance(v, (str, bytes)) Prevention
- Always convert sets/frozensets to sorted lists before passing to approx().
- If order does not matter, assert set equality directly instead of using approx().
- For custom containers, implement __getitem__ and Sized so they are recognized as sequence-like.
When it happens
Trigger: Call pytest.approx({1, 2, 3}) (a set) or any Collection lacking __getitem__. The dispatcher hits the `isinstance(expected, Collection) and not str/bytes` branch after sequence-like and Mapping checks fail.
Common situations: Passing a set to approx() expecting unordered membership comparison; passing a frozenset; passing a custom Collection that does not implement sequence protocol.
Related errors
- absolute tolerance for datetime/timedelta must be a timedelt
- relative tolerance for timedelta must be a number, got {type
- absolute tolerance can't be NaN.
- relative tolerance can't be negative: {relative_tolerance}
- relative tolerance can't be NaN.
AI-assisted analysis of pytest-dev/pytest@98b357f69e (2026-08-04).
Data as JSON: /data/errors/50f8fc0d14e4a927.json.
Report an issue: GitHub.