pytest-dev/pytest · error · TypeError
relative tolerance for a scalar value must be an int, float
Error message
relative tolerance for a scalar value must be an int, float or Decimal, got {type(rel).__name__} What it means
When constructing an ApproxScalar, the rel (relative tolerance) parameter must be None or an int, float, or Decimal. If rel is any other type (string, complex, numpy type, None mishandled), pytest raises TypeError in __init__. This validates the tolerance type before any comparison occurs.
Source
Thrown at src/_pytest/approx.py:450
# Using Real should be better than this Union, but not possible yet:
# https://github.com/python/typeshed/pull/3108
DEFAULT_ABSOLUTE_TOLERANCE: float | Decimal = 1e-12
DEFAULT_RELATIVE_TOLERANCE: float | Decimal = 1e-6
rel: float | Decimal | None
abs: float | Decimal | None
def __init__(
self,
expected: ExpectedT,
rel: float | Decimal | timedelta | None,
abs: float | Decimal | timedelta | None,
nan_ok: bool,
) -> None:
__tracebackhide__ = True
if rel is not None:
if not isinstance(rel, (int, float, Decimal)):
raise TypeError(
f"relative tolerance for a scalar value must be an int, float or Decimal, "
f"got {type(rel).__name__}"
)
if not isinstance(expected, SupportsAbs):
raise TypeError(
f"expected value must support abs(...) when relative tolerance is used, "
f"got {type(expected).__name__}"
)
if abs is not None and not isinstance(abs, (int, float, Decimal)):
raise TypeError(
f"absolute tolerance for a scalar value must be an int, float or Decimal, "
f"got {type(abs).__name__}"
)
super().__init__(expected, rel=rel, abs=abs, nan_ok=nan_ok)
def __repr__(self) -> str:
"""Return a string communicating both the expected value and the
tolerance for the comparison being made.View on GitHub (pinned to 98b357f69e)
Solutions
- Convert rel to a Python float: approx(1.0, rel=float(value)).
- Pass rel as a plain numeric literal: approx(1.0, rel=0.01).
- Use Decimal explicitly if needed: approx(Decimal('1.0'), rel=Decimal('0.01')).
Example fix
# before approx(1.0, rel='0.01') # string # after approx(1.0, rel=0.01) # float
Defensive patterns
Strategy: type-guard
Validate before calling
from decimal import Decimal
def validate_rel_tolerance(rel):
if rel is not None and not isinstance(rel, (int, float, Decimal)):
raise TypeError(f'rel must be int, float, or Decimal, got {type(rel).__name__}')
return rel Type guard
from decimal import Decimal
def is_valid_rel_tolerance(value) -> bool:
return value is None or isinstance(value, (int, float, Decimal)) Prevention
- Always pass rel as a plain float literal or variable.
- Convert config/string-sourced tolerance values with float() before passing to approx().
- Use Decimal type consistently if working with Decimal expected values.
When it happens
Trigger: Calling approx(1.0, rel='0.01') or approx(1.0, rel=np.float64(0.01)) with a non-standard numeric type. The isinstance(rel, (int, float, Decimal)) check fails.
Common situations: Passing a tolerance parsed from a config string without converting to float, or passing a numpy scalar type that isn't a Python float subclass.
Related errors
- expected value must support abs(...) when relative tolerance
- absolute tolerance for a scalar value must be an int, float
- absolute tolerance can't be negative: {absolute_tolerance}
- cannot compare '{actual}' to numpy.ndarray
- pytest.approx() does not support nested dictionaries: key={!
AI-assisted analysis of pytest-dev/pytest@98b357f69e (2026-08-04).
Data as JSON: /data/errors/7daa572e18071a41.json.
Report an issue: GitHub.