pytest-dev/pytest · error · TypeError
pytest.approx() does not support nested dictionaries: key={!
Error message
pytest.approx() does not support nested dictionaries: key={!r} value={!r}
full mapping={} What it means
pytest.approx() does not support nested dictionaries. When ApproxMapping.__init__ iterates the expected mapping, if any value is itself an instance of the same mapping type (e.g., a dict value that is also a dict), pytest raises TypeError. This is a design limitation because approx() only compares flat numeric values.
Source
Thrown at src/_pytest/approx.py:265
class ApproxMapping(Approx[Mapping[Any, Any]]):
"""Perform approximate comparisons where the expected value is a mapping
with numeric values (the keys can be anything)."""
def __init__(
self,
expected: Mapping[Any, Any],
rel: float | Decimal | timedelta | None,
abs: float | Decimal | timedelta | None,
nan_ok: bool,
) -> None:
__tracebackhide__ = True
for key, value in expected.items():
if isinstance(value, type(expected)):
msg = "pytest.approx() does not support nested dictionaries: key={!r} value={!r}\n full mapping={}"
raise TypeError(msg.format(key, value, pprint.pformat(expected)))
super().__init__(expected, rel=rel, abs=abs, nan_ok=nan_ok)
def __repr__(self) -> str:
return f"approx({ ({k: self._approx_scalar(v) for k, v in self.expected.items()})!r})"
def _repr_compare(self, other_side: Mapping[object, float]) -> list[str]:
import math
if len(self.expected) != len(other_side):
return [
"Impossible to compare mappings with different sizes.",
f"Lengths: {len(self.expected)} and {len(other_side)}",
]
if self.expected.keys() != other_side.keys():
return [
"comparison failed.",View on GitHub (pinned to 98b357f69e)
Solutions
- Flatten the dictionary before comparison, or compare sub-dicts separately.
- Use a manual recursive comparison helper for nested structures.
- Extract and compare only the numeric leaf values with individual approx() calls.
Example fix
# before
assert result == approx({'a': 1.0, 'b': {'c': 2.0}})
# after
assert result['a'] == approx(1.0)
assert result['b']['c'] == approx(2.0) Defensive patterns
Strategy: type-guard
Validate before calling
from collections.abc import Mapping
def is_flat_numeric_mapping(d: Mapping) -> bool:
"""Check that a mapping has no nested mappings (suitable for approx())."""
return all(not isinstance(v, Mapping) for v in d.values())
# usage:
# assert is_flat_numeric_mapping(expected), 'approx() requires a flat dict; flatten nested dicts first' Type guard
from collections.abc import Mapping
def is_approx_compatible_mapping(value) -> bool:
return isinstance(value, Mapping) and all(
not isinstance(v, Mapping) for v in value.values()
) Prevention
- Flatten nested dicts before passing to approx(), or compare each sub-dict separately.
- For deeply nested structures (e.g., JSON responses), write a custom recursive approx comparison.
When it happens
Trigger: Calling approx({'a': 1.0, 'b': {'c': 2.0}}). The value for key 'b' is a dict, isinstance(value, type(expected)) is True, so TypeError is raised.
Common situations: Comparing nested API responses, config dicts, or JSON-like structures that contain sub-dictionaries with floats.
Related errors
- pytest.approx() does not support nested data structures: {!r
- cannot compare '{actual}' to numpy.ndarray
- relative tolerance for a scalar value must be an int, float
- expected value must support abs(...) when relative tolerance
- absolute tolerance for a scalar value must be an int, float
AI-assisted analysis of pytest-dev/pytest@98b357f69e (2026-08-04).
Data as JSON: /data/errors/61fe9959e9e59bf9.json.
Report an issue: GitHub.