Claude commited on
Commit
77d9c47
·
unverified ·
1 Parent(s): 360239b

refactor(measurements): renommer *_runner.py en *_hooks.py pour cohérence

Browse files

Avant ce commit, le suffixe ``_runner`` était ambigu : il existait
``measurements/runner.py`` (orchestrateur central qui exécute le
benchmark) et ``measurements/{readability,searchability,
numerical_sequences,philological}_runner.py`` (couches d'adaptation
entre le calcul pur et le runner principal). Le nom suggérait
faussement que les seconds étaient des orchestrateurs.

Ces 4 fichiers sont en réalité des **hooks adaptifs** : ils calculent
une métrique par document avec adaptive masking (rien n'apparaît
pour un doc sans GT exploitable), agrègent corpus-wide, et sont
consommés par ``measurements.builtin_hooks``. Le nom ``_hooks`` les
classe avec leur consommateur naturel.

Renommages :

- ``readability_runner.py`` → ``readability_hooks.py``
- ``searchability_runner.py`` → ``searchability_hooks.py``
- ``numerical_sequences_runner.py`` → ``numerical_sequences_hooks.py``
- ``philological_runner.py`` → ``philological_hooks.py``

Tous les imports dans le code source et les tests sont migrés. Aucun
shim — les imports historiques cessent de fonctionner mais sont
substitués par les nouveaux. La docstring de
``measurements/__init__.py`` documente la convention :
``*_hooks.py`` = couche d'adaptation entre calcul pur et runner.

Le nom ``runner.py`` (sans suffixe) reste pour l'orchestrateur central
``run_benchmark`` ; c'est cohérent avec le pattern Django/Flask qui
distingue ``app.py`` (l'orchestrateur) et ``views.py`` (les hooks
de présentation).

https://claude.ai/code/session_01Hsd7kL8yeCbXn1mA7GQK9L

picarones/core/metric_hooks.py CHANGED
@@ -8,8 +8,8 @@ Avant ce chantier, ``picarones.measurements.runner._compute_document_result``
8
  contenait **11 imports tardifs codés en dur** vers
9
  ``picarones.measurements.confusion``, ``char_scores``, ``taxonomy``, ``structure``,
10
  ``image_quality``, ``line_metrics``, ``hallucination``,
11
- ``philological_runner``, ``searchability_runner``,
12
- ``numerical_sequences_runner``, ``readability_runner`` — chacun enrobé
13
  dans un ``try/except Exception`` qui logue un warning. Symétriquement,
14
  la phase d'agrégation contenait 11 fonctions ``_aggregate_*`` ou
15
  ``aggregate_*``. Ajouter une nouvelle métrique exigeait de patcher
 
8
  contenait **11 imports tardifs codés en dur** vers
9
  ``picarones.measurements.confusion``, ``char_scores``, ``taxonomy``, ``structure``,
10
  ``image_quality``, ``line_metrics``, ``hallucination``,
11
+ ``philological_hooks``, ``searchability_hooks``,
12
+ ``numerical_sequences_hooks``, ``readability_hooks`` — chacun enrobé
13
  dans un ``try/except Exception`` qui logue un warning. Symétriquement,
14
  la phase d'agrégation contenait 11 fonctions ``_aggregate_*`` ou
15
  ``aggregate_*``. Ajouter une nouvelle métrique exigeait de patcher
picarones/measurements/__init__.py CHANGED
@@ -86,7 +86,6 @@ Philologie historique :
86
  - :mod:`modern_archives` marqueurs XIXᵉ-XXᵉ
87
  - :mod:`roman_numerals` numéraux romains
88
  - :mod:`lexical_modernization` sur-normalisation lexicale
89
- - :mod:`philological_runner` câblage runner adaptive
90
 
91
  Pipelines composées (axe B) :
92
 
@@ -99,11 +98,14 @@ Aide à la décision :
99
  - :mod:`equivalence_profile` curseur fin équivalences diplomatiques
100
  - :mod:`module_policy` manifest + audit modules contribués
101
 
102
- Câblages adaptifs (suffixe ``_runner``) :
103
 
104
- - :mod:`readability_runner`, :mod:`searchability_runner`,
105
- :mod:`numerical_sequences_runner` adaptive masking
106
- document-par-document, consommés par :mod:`builtin_hooks`.
 
 
 
107
 
108
  Moteur narratif :
109
 
 
86
  - :mod:`modern_archives` marqueurs XIXᵉ-XXᵉ
87
  - :mod:`roman_numerals` numéraux romains
88
  - :mod:`lexical_modernization` sur-normalisation lexicale
 
89
 
90
  Pipelines composées (axe B) :
91
 
 
98
  - :mod:`equivalence_profile` curseur fin équivalences diplomatiques
99
  - :mod:`module_policy` manifest + audit modules contribués
100
 
101
+ Câblages adaptifs (suffixe ``_hooks``) :
102
 
103
+ - :mod:`readability_hooks`, :mod:`searchability_hooks`,
104
+ :mod:`numerical_sequences_hooks`, :mod:`philological_hooks`
105
+ adaptive masking document-par-document, consommés par
106
+ :mod:`builtin_hooks`. Ces modules sont des couches d'adaptation
107
+ entre le calcul pur (sans I/O) et le runner principal (avec
108
+ agrégation par moteur).
109
 
110
  Moteur narratif :
111
 
picarones/measurements/builtin_hooks.py CHANGED
@@ -247,7 +247,7 @@ def _image_quality_hook(*, image_path, **_):
247
  # — comportement adaptive intact.
248
  )
249
  def _philological_hook(*, ground_truth, hypothesis, **_):
250
- from picarones.measurements.philological_runner import compute_philological_metrics
251
  return compute_philological_metrics(ground_truth, hypothesis)
252
 
253
 
@@ -257,7 +257,7 @@ def _philological_hook(*, ground_truth, hypothesis, **_):
257
  profiles=_STANDARD_PROFILES,
258
  )
259
  def _searchability_hook(*, ground_truth, hypothesis, **_):
260
- from picarones.measurements.searchability_runner import compute_searchability_metrics
261
  return compute_searchability_metrics(ground_truth, hypothesis)
262
 
263
 
@@ -267,7 +267,7 @@ def _searchability_hook(*, ground_truth, hypothesis, **_):
267
  profiles=_STANDARD_PROFILES,
268
  )
269
  def _numerical_sequences_hook(*, ground_truth, hypothesis, **_):
270
- from picarones.measurements.numerical_sequences_runner import (
271
  compute_numerical_sequence_metrics_adaptive,
272
  )
273
  return compute_numerical_sequence_metrics_adaptive(ground_truth, hypothesis)
@@ -279,7 +279,7 @@ def _numerical_sequences_hook(*, ground_truth, hypothesis, **_):
279
  profiles=_STANDARD_PROFILES,
280
  )
281
  def _readability_hook(*, ground_truth, hypothesis, corpus_lang, **_):
282
- from picarones.measurements.readability_runner import compute_readability_metrics
283
  return compute_readability_metrics(ground_truth, hypothesis, lang=corpus_lang)
284
 
285
 
@@ -543,7 +543,7 @@ def _aggregate_calibration(doc_results: list) -> Optional[dict]:
543
  profiles=_STANDARD_PROFILES,
544
  )
545
  def _aggregate_philological(doc_results: list) -> Optional[dict]:
546
- from picarones.measurements.philological_runner import aggregate_philological_metrics
547
  return aggregate_philological_metrics(
548
  [dr.philological_metrics for dr in doc_results],
549
  )
@@ -555,7 +555,7 @@ def _aggregate_philological(doc_results: list) -> Optional[dict]:
555
  profiles=_STANDARD_PROFILES,
556
  )
557
  def _aggregate_searchability(doc_results: list) -> Optional[dict]:
558
- from picarones.measurements.searchability_runner import aggregate_searchability_metrics
559
  return aggregate_searchability_metrics(
560
  [dr.searchability_metrics for dr in doc_results],
561
  )
@@ -567,7 +567,7 @@ def _aggregate_searchability(doc_results: list) -> Optional[dict]:
567
  profiles=_STANDARD_PROFILES,
568
  )
569
  def _aggregate_numerical_sequences(doc_results: list) -> Optional[dict]:
570
- from picarones.measurements.numerical_sequences_runner import (
571
  aggregate_numerical_sequence_metrics,
572
  )
573
  return aggregate_numerical_sequence_metrics(
@@ -581,7 +581,7 @@ def _aggregate_numerical_sequences(doc_results: list) -> Optional[dict]:
581
  profiles=_STANDARD_PROFILES,
582
  )
583
  def _aggregate_readability(doc_results: list) -> Optional[dict]:
584
- from picarones.measurements.readability_runner import aggregate_readability_metrics
585
  return aggregate_readability_metrics(
586
  [dr.readability_metrics for dr in doc_results],
587
  )
 
247
  # — comportement adaptive intact.
248
  )
249
  def _philological_hook(*, ground_truth, hypothesis, **_):
250
+ from picarones.measurements.philological_hooks import compute_philological_metrics
251
  return compute_philological_metrics(ground_truth, hypothesis)
252
 
253
 
 
257
  profiles=_STANDARD_PROFILES,
258
  )
259
  def _searchability_hook(*, ground_truth, hypothesis, **_):
260
+ from picarones.measurements.searchability_hooks import compute_searchability_metrics
261
  return compute_searchability_metrics(ground_truth, hypothesis)
262
 
263
 
 
267
  profiles=_STANDARD_PROFILES,
268
  )
269
  def _numerical_sequences_hook(*, ground_truth, hypothesis, **_):
270
+ from picarones.measurements.numerical_sequences_hooks import (
271
  compute_numerical_sequence_metrics_adaptive,
272
  )
273
  return compute_numerical_sequence_metrics_adaptive(ground_truth, hypothesis)
 
279
  profiles=_STANDARD_PROFILES,
280
  )
281
  def _readability_hook(*, ground_truth, hypothesis, corpus_lang, **_):
282
+ from picarones.measurements.readability_hooks import compute_readability_metrics
283
  return compute_readability_metrics(ground_truth, hypothesis, lang=corpus_lang)
284
 
285
 
 
543
  profiles=_STANDARD_PROFILES,
544
  )
545
  def _aggregate_philological(doc_results: list) -> Optional[dict]:
546
+ from picarones.measurements.philological_hooks import aggregate_philological_metrics
547
  return aggregate_philological_metrics(
548
  [dr.philological_metrics for dr in doc_results],
549
  )
 
555
  profiles=_STANDARD_PROFILES,
556
  )
557
  def _aggregate_searchability(doc_results: list) -> Optional[dict]:
558
+ from picarones.measurements.searchability_hooks import aggregate_searchability_metrics
559
  return aggregate_searchability_metrics(
560
  [dr.searchability_metrics for dr in doc_results],
561
  )
 
567
  profiles=_STANDARD_PROFILES,
568
  )
569
  def _aggregate_numerical_sequences(doc_results: list) -> Optional[dict]:
570
+ from picarones.measurements.numerical_sequences_hooks import (
571
  aggregate_numerical_sequence_metrics,
572
  )
573
  return aggregate_numerical_sequence_metrics(
 
581
  profiles=_STANDARD_PROFILES,
582
  )
583
  def _aggregate_readability(doc_results: list) -> Optional[dict]:
584
+ from picarones.measurements.readability_hooks import aggregate_readability_metrics
585
  return aggregate_readability_metrics(
586
  [dr.readability_metrics for dr in doc_results],
587
  )
picarones/measurements/{numerical_sequences_runner.py → numerical_sequences_hooks.py} RENAMED
File without changes
picarones/measurements/{philological_runner.py → philological_hooks.py} RENAMED
@@ -123,7 +123,7 @@ def compute_philological_metrics(
123
  result = compute_fn(ref, hypothesis or "")
124
  except Exception as exc: # pragma: no cover — défense en profondeur
125
  logger.warning(
126
- "[philological_runner] module %s a échoué : %s", name, exc,
127
  )
128
  continue
129
  if has_signal_fn(result):
@@ -350,7 +350,7 @@ def aggregate_philological_metrics(
350
  aggregator = _AGGREGATORS.get(module)
351
  if aggregator is None: # pragma: no cover
352
  logger.warning(
353
- "[philological_runner] aucun agrégateur pour %s", module,
354
  )
355
  continue
356
  out[module] = aggregator(payloads)
 
123
  result = compute_fn(ref, hypothesis or "")
124
  except Exception as exc: # pragma: no cover — défense en profondeur
125
  logger.warning(
126
+ "[philological_hooks] module %s a échoué : %s", name, exc,
127
  )
128
  continue
129
  if has_signal_fn(result):
 
350
  aggregator = _AGGREGATORS.get(module)
351
  if aggregator is None: # pragma: no cover
352
  logger.warning(
353
+ "[philological_hooks] aucun agrégateur pour %s", module,
354
  )
355
  continue
356
  out[module] = aggregator(payloads)
picarones/measurements/{readability_runner.py → readability_hooks.py} RENAMED
File without changes
picarones/measurements/{searchability_runner.py → searchability_hooks.py} RENAMED
File without changes
tests/test_sprint61_philological_runner.py CHANGED
@@ -24,7 +24,7 @@ Couvre :
24
 
25
  from __future__ import annotations
26
 
27
- from picarones.measurements.philological_runner import (
28
  aggregate_philological_metrics,
29
  compute_philological_metrics,
30
  )
 
24
 
25
  from __future__ import annotations
26
 
27
+ from picarones.measurements.philological_hooks import (
28
  aggregate_philological_metrics,
29
  compute_philological_metrics,
30
  )
tests/test_sprint86_aii5_html.py CHANGED
@@ -18,7 +18,7 @@ from __future__ import annotations
18
  import json
19
  from pathlib import Path
20
 
21
- from picarones.measurements.numerical_sequences_runner import (
22
  aggregate_numerical_sequence_metrics,
23
  compute_numerical_sequence_metrics_adaptive,
24
  )
@@ -32,7 +32,7 @@ def _stub_metrics() -> MetricsResult:
32
  wer=0.0, wer_normalized=0.0, mer=0.0, wil=0.0,
33
  reference_length=0, hypothesis_length=0,
34
  )
35
- from picarones.measurements.searchability_runner import (
36
  aggregate_searchability_metrics,
37
  compute_searchability_metrics,
38
  )
 
18
  import json
19
  from pathlib import Path
20
 
21
+ from picarones.measurements.numerical_sequences_hooks import (
22
  aggregate_numerical_sequence_metrics,
23
  compute_numerical_sequence_metrics_adaptive,
24
  )
 
32
  wer=0.0, wer_normalized=0.0, mer=0.0, wil=0.0,
33
  reference_length=0, hypothesis_length=0,
34
  )
35
+ from picarones.measurements.searchability_hooks import (
36
  aggregate_searchability_metrics,
37
  compute_searchability_metrics,
38
  )
tests/test_sprint87_readability_html.py CHANGED
@@ -17,7 +17,7 @@ import json
17
  from pathlib import Path
18
 
19
  from picarones.measurements.metrics import MetricsResult
20
- from picarones.measurements.readability_runner import (
21
  aggregate_readability_metrics,
22
  compute_readability_metrics,
23
  )
 
17
  from pathlib import Path
18
 
19
  from picarones.measurements.metrics import MetricsResult
20
+ from picarones.measurements.readability_hooks import (
21
  aggregate_readability_metrics,
22
  compute_readability_metrics,
23
  )