Picarones / tests /measurements /_helpers.py
Claude
chore: supprimer unregister_job mort + factoriser _numbers_in_payload partagé
d40d01e unverified
Raw
History Blame
1.69 kB
"""Helpers partagés par les tests ``tests/measurements/``.
Centralise des utilitaires de test réutilisés par plusieurs fichiers
sprint, en particulier le garde-fou anti-hallucination du moteur
narratif.
"""
from __future__ import annotations
import re
from typing import Any
def numbers_in_payload(payload: Any) -> set[str]:
"""Collecte toutes les représentations numériques d'un payload de Fact.
Inclut les variantes usuelles produites par ``str.format`` :
``5``, ``5.0``, ``5.00``, ``5.000``, ``5.0000``, etc., pour tolérer
les patterns ``{x}`` et ``{x:.2f}`` dans les templates narratifs.
Le walk est récursif (dict / list / tuple) et parse également les
chaînes via ``\\d+(?:\\.\\d+)?`` pour couvrir les payloads où une
valeur numérique a été pré-formatée en string.
"""
out: set[str] = set()
def _add_variants(v: Any) -> None:
try:
f = float(v)
except (TypeError, ValueError):
return
out.add(str(v))
out.add(str(f))
if f == int(f):
out.add(str(int(f)))
for dec in (1, 2, 3, 4):
out.add(f"{f:.{dec}f}")
def _walk(x: Any) -> None:
if isinstance(x, dict):
for v in x.values():
_walk(v)
elif isinstance(x, (list, tuple)):
for v in x:
_walk(v)
elif isinstance(x, bool):
return
elif isinstance(x, (int, float)):
_add_variants(x)
elif isinstance(x, str):
for n in re.findall(r"\d+(?:\.\d+)?", x):
_add_variants(n)
_walk(payload)
return out
__all__ = ["numbers_in_payload"]