Coverage for dataexcept/_validation.py: 100%
5 statements
« prev ^ index » next coverage.py v7.15.4, created at 2026-09-03 20:46 +0000
« prev ^ index » next coverage.py v7.15.4, created at 2026-09-03 20:46 +0000
1"""Small runtime checks shared by the exception constructors."""
3from __future__ import annotations
5import numbers
7__all__ = ["is_number"]
10def is_number(value: object) -> bool:
11 """Return True for any real number, including NumPy scalars.
13 ``isinstance(value, (int, float))`` rejects ``numpy.float32`` and
14 ``numpy.int64``, which is a poor answer from a library aimed at data
15 science. ``numbers.Real`` accepts them because NumPy registers its scalar
16 types with the ABC, and it needs no dependency on NumPy to do so.
18 Booleans are excluded: ``bool`` subclasses ``int``, so ``numbers.Real``
19 would accept ``True`` as a metric.
21 This is a function rather than an inline ``isinstance`` because narrowing a
22 value to ``numbers.Real`` defeats mypy's inference for the rest of the
23 enclosing class.
24 """
25 # bool subclasses int, so numbers.Real accepts True and False. A boolean
26 # is never a meaningful metric, threshold or ratio, and accepting one hides
27 # a caller passing the wrong variable.
28 return not isinstance(value, bool) and isinstance(value, numbers.Real)