diff --git a/CLAUDE.md b/CLAUDE.md index 35d9cd5e42e74f70e03c892f39f42eb726847b52..64a4ebe7defeee93530e9e4885588186d54a411d 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -118,7 +118,7 @@ picarones/ ## État des tests et bugs historiques -`pytest tests/` → **5080 passed, 12 skipped, 8 deselected, 0 failed** +`pytest tests/` → **5040 passed, 12 skipped, 8 deselected, 0 failed** (post-S59). Les deselected sont les markers `live` (5 tests d'intégration contre vraie API/binaire) + `network` (3 tests qui hit le réseau réel), opt-in en local via `pytest -m live` ou `pytest -m network`. Le @@ -156,7 +156,7 @@ correspondants (`test_sprint15_llm_pipeline_bugs.py`, `test_sprint8_escriptorium CI, Makefile et invocation directe produisent le même résultat. Le job `lint` du CI est bloquant — un F401 (import inutilisé) ou un E741 (variable ambiguë) fait échouer la PR, par design. -- **Les profils de normalisation** sont dans `picarones/measurements/normalization.py` — l'endpoint +- **Les profils de normalisation** sont dans `picarones/formats/text/normalization.py` — l'endpoint `/api/normalization/profiles` doit les lire dynamiquement depuis ce fichier, pas depuis une liste statique. @@ -248,7 +248,7 @@ Résumé express : 1. `git branch --show-current` → `claude/repo-analysis-cukvm`. 2. `git status` → working tree clean. -3. `pytest tests/ -q --no-header --tb=line` → 5080 passed. +3. `pytest tests/ -q --no-header --tb=line` → 5040 passed. 4. `git log -1 --format=%B` → décrit la prochaine sub-phase. **Règles d'architecture critiques** (apprises à la dure) : @@ -336,7 +336,7 @@ détecte, arbitre, rend. ## Contexte développement - **Environnement** : GitHub Codespaces, Python 3.11+ -- **Tests** : `pytest tests/ -q` → 5080 passed, 12 skipped, 24 +- **Tests** : `pytest tests/ -q` → 5040 passed, 12 skipped, 24 deselected, 0 failed (au moment de la pause de session). - **Plan d'évolution actif** : [`docs/roadmap/evolution-2026.md`](docs/roadmap/evolution-2026.md). - **Plan retrait du legacy (maître)** : [`docs/migration/legacy-retirement-plan.md`](docs/migration/legacy-retirement-plan.md). diff --git a/README.md b/README.md index a968f03362aa5472e5e907aa5d3b89d99583e1c9..dc866f5335e6c35280d69cfd43c6bb992788ef42 100644 --- a/README.md +++ b/README.md @@ -299,7 +299,7 @@ client generation. Picarones ships **11 built-in normalization profiles** for historical text comparison (defined in -[`picarones/measurements/normalization.py`](picarones/measurements/normalization.py), +[`picarones/formats/text/normalization.py`](picarones/formats/text/normalization.py), exposed via `/api/normalization/profiles`): `nfc`, `caseless`, `minimal`, `medieval_french`, @@ -395,7 +395,7 @@ ruff check picarones/ tests/ python -m mypy picarones/core/ ``` -**Test suite**: ~5080 tests, ~3 min on a modern laptop. Coverage +**Test suite**: ~5040 tests, ~3 min on a modern laptop. Coverage floor at 85% (currently ~87%). The `network` marker excludes tests requiring live HTTP. A handful of tests depend on optional engines (`pero-ocr`, `pytesseract`) and are skipped/fail gracefully when diff --git a/SPECS.md b/SPECS.md index d8104dd7956a1333fa825f4a4bf275884cfb7fff..02b395d9876c867d66eede7d10bfeda05e97eed6 100644 --- a/SPECS.md +++ b/SPECS.md @@ -467,7 +467,7 @@ canonique (champ `reference`). ### 6.2 Profils de normalisation -11 profils livrés (`picarones/measurements/normalization.py`, +11 profils livrés (`picarones/formats/text/normalization.py`, exposés via `/api/normalization/profiles`) : `nfc`, `caseless`, `minimal`, `medieval_french`, `early_modern_french`, `medieval_latin`, `medieval_english`, `early_modern_english`, diff --git a/docs/migration/SESSION_HANDOVER.md b/docs/migration/SESSION_HANDOVER.md index cba0b3e33e486f362ac2355f314be4415f1bde14..f172e9dd0b5e6bb505ca500a21b9a36c8d4b6fc7 100644 --- a/docs/migration/SESSION_HANDOVER.md +++ b/docs/migration/SESSION_HANDOVER.md @@ -203,12 +203,13 @@ fiable.) ### 4.A Imports legacy dans les tests -**91 fichiers** avec **472 statements** d'import depuis les +**66 fichiers** avec **372 statements** d'import depuis les paquets legacy (``core``, ``measurements``, ``engines``, -``llm``, ``pipelines``, ``report``, ``modules``) — Lots A, B et -C terminés (cf. 4.D ci-dessous). Le sous-paquet ``core/`` ne -contient plus que ``diff_utils`` et ``xml_utils`` (à migrer en -Lot G ou plus tard). +``llm``, ``pipelines``, ``report``, ``modules``) — Lots A, B, +C et D terminés (cf. 4.D ci-dessous). Le sous-paquet +``core/`` ne contient plus que ``diff_utils`` et ``xml_utils``, +et ``measurements/`` est passé de 50+ shims à ~25 modules +réellement présents. Top chemins consommés : @@ -218,7 +219,7 @@ Top chemins consommés : | 18 | ``from picarones.measurements.metrics import MetricsResult`` | | 16 | ``from picarones.measurements.statistics import wilcoxon_test`` | | 13 | ``from picarones.measurements.metrics import compute_metrics`` | -| 10 | ``from picarones.measurements.normalization import get_builtin_profile`` | +| 10 | ``from picarones.measurements.robustness import degrade_image_bytes`` | **Pourquoi c'est important** : ces tests passent par les shims au lieu de pointer vers le canonique. Tant que ces imports @@ -228,8 +229,9 @@ existent, on **ne peut pas supprimer les shims** (le test casse). commit, avancer. Shims supprimés dans les Lots A (``core.modules`` + ``core.facts``), B (``core.metric_registry`` + ``core.metric_hooks`` + -``core.metrics``) et C (``core.results`` + ``core.corpus`` + -``core.pipeline``) sur la branche +``core.metrics``), C (``core.results`` + ``core.corpus`` + +``core.pipeline``) et D (34 shims plats de ``measurements/`` +vers ``evaluation.metrics/``) sur la branche ``claude/migrate-core-to-domain-8ubIT``. ### 4.B Imports legacy en production (hors shims eux-mêmes) @@ -284,9 +286,30 @@ L'ordre recommandé, par lots de symboles cohérents : migrées vers les chemins canoniques ; logger filter dans ``test_sprint32_multi_level_gt`` aligné sur ``picarones.evaluation.corpus``. -4. **Lot D — evaluation/metrics/*** (~80 imports) : - - ``measurements.{difficulty, taxonomy, calibration, …}`` → - ``evaluation.metrics.{...}`` +4. ✅ **Lot D — evaluation/metrics/*** (~100 imports + 44 + prod migrés, 34 shims supprimés en bloc) : + - ``measurements.{baseline_comparison, calibration, + char_scores, confusion, cost_projection, difficulty, + error_absorption, hallucination, image_predictive, + image_quality, incremental_comparison, inter_engine, + layout, levers, lexical_modernization, line_metrics, + longitudinal, marginal_cost, module_policy, ner_backends, + normalization, numerical_sequences, pricing, rare_tokens, + robustness_projection, roman_numerals, specialization, + structure, taxonomy, taxonomy_comparison, + taxonomy_cooccurrence, taxonomy_intra_doc, throughput, + worst_lines}`` → ``evaluation.metrics.{...}``. + - ``picarones/measurements/__init__.py`` réécrit pour + refléter la nouvelle composition (modules legacy + restants + `import picarones.evaluation.metrics` + unique pour déclencher les décorateurs). + - ``test_no_flat_files_in_measurements::WHITELIST_FLAT_FILES_S3`` + réduit de 60 → 25 entrées. + - ``test_module_coverage::TEST_ONLY_BASELINE`` réduit + de 16 → 4 entrées. + - ``test_file_budgets::FILE_BUDGETS`` débarrassé des + entrées orphelines (inter_engine, levers, + normalization). 5. **Lot E — adapters/legacy_*** (~50 imports) : - ``engines.*`` → ``adapters.legacy_engines.*`` - ``modules.alto_text_to_mono_region`` → diff --git a/picarones/fixtures.py b/picarones/fixtures.py index 96ff84c43002d465d9795b30c48ff5146b5d91eb..88de8b30808481757eeecb49e883412671dfb0b3 100644 --- a/picarones/fixtures.py +++ b/picarones/fixtures.py @@ -17,15 +17,15 @@ from picarones.measurements.metrics import MetricsResult from picarones.evaluation.benchmark_result import BenchmarkResult, DocumentResult, EngineReport from picarones.pipelines.over_normalization import detect_over_normalization # Sprint 5 — métriques avancées -from picarones.measurements.confusion import build_confusion_matrix -from picarones.measurements.char_scores import compute_ligature_score, compute_diacritic_score -from picarones.measurements.taxonomy import classify_errors, aggregate_taxonomy -from picarones.measurements.structure import analyze_structure, aggregate_structure -from picarones.measurements.image_quality import generate_mock_quality_scores, aggregate_image_quality -from picarones.measurements.char_scores import aggregate_ligature_scores, aggregate_diacritic_scores +from picarones.evaluation.metrics.confusion import build_confusion_matrix +from picarones.evaluation.metrics.char_scores import compute_ligature_score, compute_diacritic_score +from picarones.evaluation.metrics.taxonomy import classify_errors, aggregate_taxonomy +from picarones.evaluation.metrics.structure import analyze_structure, aggregate_structure +from picarones.evaluation.metrics.image_quality import generate_mock_quality_scores, aggregate_image_quality +from picarones.evaluation.metrics.char_scores import aggregate_ligature_scores, aggregate_diacritic_scores # Sprint 10 — distribution des erreurs + hallucinations VLM -from picarones.measurements.line_metrics import compute_line_metrics, aggregate_line_metrics, LineMetrics -from picarones.measurements.hallucination import compute_hallucination_metrics, aggregate_hallucination_metrics +from picarones.evaluation.metrics.line_metrics import compute_line_metrics, aggregate_line_metrics, LineMetrics +from picarones.evaluation.metrics.hallucination import compute_hallucination_metrics, aggregate_hallucination_metrics # --------------------------------------------------------------------------- # Textes GT réalistes (documents patrimoniaux) @@ -427,11 +427,11 @@ def generate_sample_benchmark( } # Agrégation Sprint 5 - from picarones.measurements.confusion import aggregate_confusion_matrices, ConfusionMatrix - from picarones.measurements.char_scores import LigatureScore, DiacriticScore - from picarones.measurements.taxonomy import TaxonomyResult - from picarones.measurements.structure import StructureResult - from picarones.measurements.image_quality import ImageQualityResult + from picarones.evaluation.metrics.confusion import aggregate_confusion_matrices, ConfusionMatrix + from picarones.evaluation.metrics.char_scores import LigatureScore, DiacriticScore + from picarones.evaluation.metrics.taxonomy import TaxonomyResult + from picarones.evaluation.metrics.structure import StructureResult + from picarones.evaluation.metrics.image_quality import ImageQualityResult agg_confusion = aggregate_confusion_matrices([ ConfusionMatrix(**dr.confusion_matrix) @@ -468,7 +468,7 @@ def generate_sample_benchmark( LineMetrics.from_dict(dr.line_metrics) for dr in doc_results if dr.line_metrics ]) - from picarones.measurements.hallucination import HallucinationMetrics as _HM + from picarones.evaluation.metrics.hallucination import HallucinationMetrics as _HM agg_hallucination = aggregate_hallucination_metrics([ _HM.from_dict(dr.hallucination_metrics) for dr in doc_results if dr.hallucination_metrics diff --git a/picarones/measurements/__init__.py b/picarones/measurements/__init__.py index b77c6f797ced538c287d93bd0e9f081b60c0f0f2..2f189f8ef65ababcc4fe73e93eca6cb192131822 100644 --- a/picarones/measurements/__init__.py +++ b/picarones/measurements/__init__.py @@ -1,14 +1,11 @@ -"""Métriques officielles Picarones — Cercle 2. +"""Métriques officielles Picarones — paquet legacy en cours de retrait. -Ce package contient l'ensemble des mesures et analyses qui calculent, -agrègent ou interprètent des métriques sur un corpus. Il dépend du -cercle 1 (``picarones.core``) qui définit les abstractions, et est -consommé par le cercle 3 (``picarones.report``, ``picarones.cli``, -``picarones.web``) qui présente les résultats. +Ce paquet, historiquement nommé « Cercle 2 — logique métier », est +progressivement vidé au profit du paquet canonique +:mod:`picarones.evaluation.metrics`. Les modules qui restent ici ne +sont pas encore migrés (Catégorie B/C/D du plan de migration) : -Sous-modules ------------- -Coeur : +Coeur (toujours legacy) : - :mod:`metrics` compute_metrics (CER/WER/MER/WIL via jiwer) - :mod:`statistics` Wilcoxon, Friedman, Nemenyi, Pareto, CDD @@ -16,96 +13,46 @@ Coeur : - :mod:`builtin_hooks` 12 hooks doc + 12 agrégateurs natifs - :mod:`builtin_metrics` enregistrement métriques dans le registry - :mod:`alto_metrics` métriques jonction TEXT/ALTO -- :mod:`normalization` profils Unicode -Erreurs et taxonomie : +Métriques philologiques (Catégorie B — register_metric singleton) : -- :mod:`confusion` matrice de confusion Unicode -- :mod:`char_scores` scores ligatures/diacritiques -- :mod:`taxonomy` taxonomie 9 classes d'erreurs -- :mod:`taxonomy_comparison` comparaison taxonomique miroir -- :mod:`taxonomy_cooccurrence` Jaccard inter-classes -- :mod:`taxonomy_intra_doc` heatmap classes × position +- :mod:`mufi`, :mod:`abbreviations`, :mod:`unicode_blocks`, + :mod:`early_modern_typography`, :mod:`modern_archives`, + :mod:`reading_order`, :mod:`ner`, :mod:`readability`, + :mod:`searchability`. -Structure et lignes : - -- :mod:`structure` blocs/lignes/mots -- :mod:`line_metrics` distribution CER par ligne (Gini, percentiles) -- :mod:`worst_lines` lignes pires globales - -Fiabilité et calibration : - -- :mod:`calibration` ECE, MCE, reliability bins -- :mod:`reliability` IAA Cohen κ + multirun stability -- :mod:`hallucination` détection hallucinations VLM -- :mod:`robustness` courbes CER vs dégradation -- :mod:`robustness_projection` projection sur corpus réel - -Image et difficulté : - -- :mod:`image_quality` contraste, bruit, flou… -- :mod:`image_predictive` complexité paléographique -- :mod:`difficulty` score difficulté intrinsèque - -Contenu et lisibilité : - -- :mod:`searchability` recherchabilité fuzzy (Levenshtein) -- :mod:`numerical_sequences` préservation dates/cotes/numéraux -- :mod:`rare_tokens` rappel sur tokens rares -- :mod:`readability` Δ Flesch (sur-normalisation) - -Structure ALTO et entités : - -- :mod:`layout` F1 layout par type de région -- :mod:`reading_order` F1 ordre de lecture (ICDAR 2015) -- :mod:`ner`, :mod:`ner_backends` -- :mod:`error_absorption` correction vs introduction par jonction - -Inter-moteurs et historique : - -- :mod:`inter_engine` divergence taxonomique + oracle gap -- :mod:`specialization` spécialisation inter-moteurs -- :mod:`baseline_comparison` comparaison à l'historique -- :mod:`longitudinal` régression linéaire + change-point -- :mod:`incremental_comparison` ANOVA-like par slot -- :mod:`history` historique SQLite - -Économie et opération : - -- :mod:`pricing` table tarifaire -- :mod:`throughput` pages/h effectif -- :mod:`cost_projection` projection à volume cible -- :mod:`marginal_cost` coût par erreur évitée - -Philologie historique : +Câblages adaptifs (suffixe ``_hooks``) : -- :mod:`mufi` couverture MUFI (médiéval) -- :mod:`abbreviations` signes d'abréviation Capelli -- :mod:`unicode_blocks` précision par bloc Unicode -- :mod:`early_modern_typography` ligatures imprimées XVIᵉ-XVIIIᵉ -- :mod:`modern_archives` marqueurs XIXᵉ-XXᵉ -- :mod:`roman_numerals` numéraux romains -- :mod:`lexical_modernization` sur-normalisation lexicale +- :mod:`readability_hooks`, :mod:`searchability_hooks`, + :mod:`numerical_sequences_hooks`, :mod:`philological_hooks`. Pipelines composées (axe B) : - :mod:`pipeline_benchmark`, :mod:`pipeline_comparison`, - :mod:`pipeline_spec_loader` - -Aide à la décision : - -- :mod:`levers` leviers d'amélioration factuels -- :mod:`equivalence_profile` curseur fin équivalences diplomatiques -- :mod:`module_policy` manifest + audit modules contribués - -Câblages adaptifs (suffixe ``_hooks``) : - -- :mod:`readability_hooks`, :mod:`searchability_hooks`, - :mod:`numerical_sequences_hooks`, :mod:`philological_hooks` — - adaptive masking document-par-document, consommés par - :mod:`builtin_hooks`. Ces modules sont des couches d'adaptation - entre le calcul pur (sans I/O) et le runner principal (avec - agrégation par moteur). + :mod:`pipeline_spec_loader`. + +Auxiliaires : + +- :mod:`equivalence_profile`, :mod:`reliability`, :mod:`history`, + :mod:`robustness`. + +Modules retirés (Lot D, mai 2026) +--------------------------------- +Tous les shims qui ne faisaient que ré-exporter +``picarones.evaluation.metrics.X`` ont été supprimés en bloc : +``baseline_comparison``, ``calibration``, ``char_scores``, +``confusion``, ``cost_projection``, ``difficulty``, +``error_absorption``, ``hallucination``, ``image_predictive``, +``image_quality``, ``incremental_comparison``, ``inter_engine``, +``layout``, ``levers``, ``lexical_modernization``, +``line_metrics``, ``longitudinal``, ``marginal_cost``, +``module_policy``, ``ner_backends``, ``normalization``, +``numerical_sequences``, ``pricing``, ``rare_tokens``, +``robustness_projection``, ``roman_numerals``, ``specialization``, +``structure``, ``taxonomy``, ``taxonomy_comparison``, +``taxonomy_cooccurrence``, ``taxonomy_intra_doc``, ``throughput``, +``worst_lines``. Importer désormais depuis +:mod:`picarones.evaluation.metrics`. Moteur narratif : @@ -114,35 +61,28 @@ Moteur narratif : ``FactType``, ``DetectorRegistry``) vit en couche 1 dans :mod:`picarones.domain.facts`. -Voir :doc:`docs/explanation/architecture.md` pour la cartographie complète et -la règle de dépendance des 3 cercles. +Voir :doc:`docs/explanation/architecture.md` pour la cartographie complète. """ # ────────────────────────────────────────────────────────────────────────── -# Sprint A3 (renforce le respect de la règle Cercle 2 → Cercle 1 -# uniquement) — la cérémonie d'enregistrement des métriques typées dans -# le registre Sprint 34 a été déplacée ici depuis ``core/pipeline.py`` -# qui violait la règle. -# -# Tout consommateur qui veut utiliser ``compute_at_junction`` -# (``picarones.evaluation.metric_registry``) doit avoir importé -# ``picarones.measurements`` au moins une fois pour que les décorateurs -# ``@register_metric`` aient été exécutés. C'est le cas par défaut dans -# le pipeline standard ; les notebooks isolés peuvent ajouter -# ``import picarones.measurements`` (suivi d'un commentaire d'exception -# ruff sur la ligne d'import si leur linter signale un import inutilisé). +# Cérémonie d'enregistrement des métriques typées dans le registre +# Sprint 34. Tout consommateur qui veut utiliser ``compute_at_junction`` +# (``picarones.evaluation.metric_registry``) doit avoir importé soit +# ``picarones.measurements`` soit ``picarones.evaluation.metrics`` au +# moins une fois pour que les décorateurs ``@register_metric`` aient +# été exécutés. # # Sans ces imports, ``compute_at_junction`` trouverait un registre vide # et ne calculerait rien aux jonctions. # ────────────────────────────────────────────────────────────────────────── + # Sprint 34 : cer / wer / mer / wil + stub TEXT→ALTO from picarones.measurements import builtin_metrics # noqa: F401 -# Sprints 55-60 : métriques philologiques. +# Sprints 55-60 : métriques philologiques (Catégorie B — restent ici). from picarones.measurements import abbreviations # noqa: F401 from picarones.measurements import early_modern_typography # noqa: F401 from picarones.measurements import modern_archives # noqa: F401 from picarones.measurements import mufi # noqa: F401 -from picarones.measurements import roman_numerals # noqa: F401 from picarones.measurements import unicode_blocks # noqa: F401 # Sprint 53 : reading order F1. Sprints 38, 52 : NER, readability. from picarones.measurements import ner # noqa: F401 @@ -152,27 +92,19 @@ from picarones.measurements import reading_order # noqa: F401 # les reconstructeurs ALTO contre une GT ALTO du document. from picarones.measurements import alto_metrics # noqa: F401 -# ────────────────────────────────────────────────────────────────────────── -# Sprint « zéro dette actionnable » (mai 2026) — modules sans appel -# automatique par le runner OCR principal mais qui font partie de l'API -# publique de ``picarones.measurements``. L'import ici les rend -# accessibles en ``from picarones.measurements import X`` et garantit -# qu'aucun ne devient « test-only » silencieusement (cf. -# ``tests/architecture/test_module_coverage.py``). -# -# Distinction de scope : -# - Modules de calcul utilisés via les renderers HTML composables -# (l'utilisateur les compose lui-même selon son use case) : -from picarones.measurements import baseline_comparison # noqa: F401 # historique SQLite -from picarones.measurements import cost_projection # noqa: F401 # volume cible utilisateur +# Lot D — les décorateurs ``@register_metric`` du paquet canonique +# ``picarones.evaluation.metrics`` sont exécutés dès cet import, +# garantissant que le registre Sprint 34 contient toutes les métriques +# canoniques sans avoir besoin des shims supprimés. +import picarones.evaluation.metrics # noqa: F401 + +# Modules conservés en couche measurements (pas de shim canonique +# correspondant ; restent ici jusqu'à leur propre relocalisation). from picarones.measurements import equivalence_profile # noqa: F401 # curseur HTML -from picarones.measurements import error_absorption # noqa: F401 # jonction pipeline composée -from picarones.measurements import layout # noqa: F401 # GT ALTO requise (axe B) -from picarones.measurements import longitudinal # noqa: F401 # historique SQLite -from picarones.measurements import marginal_cost # noqa: F401 # paires de moteurs -from picarones.measurements import module_policy # noqa: F401 # outil d'audit -from picarones.measurements import ner_backends # noqa: F401 # factory backends NER -from picarones.measurements import rare_tokens # noqa: F401 # corpus-wide from picarones.measurements import reliability # noqa: F401 # multi-runs -from picarones.measurements import taxonomy_cooccurrence # noqa: F401 # depuis taxonomy -from picarones.measurements import taxonomy_intra_doc # noqa: F401 # depuis taxonomy + +# Modules canoniques re-exposés pour rétrocompat de +# ``from picarones.measurements import roman_numerals`` (utilisé par +# d'anciens callers internes ; au prochain Lot, ils migreront vers +# ``picarones.evaluation.metrics.roman_numerals``). +from picarones.evaluation.metrics import roman_numerals # noqa: F401 diff --git a/picarones/measurements/baseline_comparison.py b/picarones/measurements/baseline_comparison.py deleted file mode 100644 index 7c886ab031814efafd7d14b634fd9fcf3ce90f05..0000000000000000000000000000000000000000 --- a/picarones/measurements/baseline_comparison.py +++ /dev/null @@ -1,10 +0,0 @@ -"""Re-export — Sprint A14-S10. Le contenu canonique vit dans -``picarones.evaluation.metrics.baseline_comparison``. - -L'ancien chemin ``picarones.measurements.baseline_comparison`` est conservé pour -ne casser aucun consommateur. Au S22, ce re-export disparaîtra. -""" - -from __future__ import annotations - -from picarones.evaluation.metrics.baseline_comparison import * # noqa: F401,F403 diff --git a/picarones/measurements/builtin_hooks.py b/picarones/measurements/builtin_hooks.py index e8aebde7484e6b280518b946b3e91cfd29eb36a1..e5e32f8449c080530f69e8cadd5b62927ba9d5cd 100644 --- a/picarones/measurements/builtin_hooks.py +++ b/picarones/measurements/builtin_hooks.py @@ -97,7 +97,7 @@ def calibration_from_engine_result( normalisées à ``[0, 1]``. Les confidences négatives (Tesseract met -1 pour les non-mots) sont ignorées. """ - from picarones.measurements.calibration import compute_calibration_metrics + from picarones.evaluation.metrics.calibration import compute_calibration_metrics if not token_confidences: return None @@ -146,7 +146,7 @@ def calibration_from_engine_result( requires_success=True, ) def _confusion_hook(*, ground_truth, hypothesis, **_): - from picarones.measurements.confusion import build_confusion_matrix + from picarones.evaluation.metrics.confusion import build_confusion_matrix return build_confusion_matrix(ground_truth, hypothesis).as_dict() @@ -157,7 +157,7 @@ def _confusion_hook(*, ground_truth, hypothesis, **_): requires_success=True, ) def _char_scores_hook(*, ground_truth, hypothesis, **_): - from picarones.measurements.char_scores import ( + from picarones.evaluation.metrics.char_scores import ( compute_diacritic_score, compute_ligature_score, ) @@ -173,7 +173,7 @@ def _char_scores_hook(*, ground_truth, hypothesis, **_): requires_success=True, ) def _taxonomy_hook(*, ground_truth, hypothesis, **_): - from picarones.measurements.taxonomy import classify_errors + from picarones.evaluation.metrics.taxonomy import classify_errors return classify_errors(ground_truth, hypothesis).as_dict() @@ -184,7 +184,7 @@ def _taxonomy_hook(*, ground_truth, hypothesis, **_): requires_success=True, ) def _structure_hook(*, ground_truth, hypothesis, **_): - from picarones.measurements.structure import analyze_structure + from picarones.evaluation.metrics.structure import analyze_structure return analyze_structure(ground_truth, hypothesis).as_dict() @@ -195,7 +195,7 @@ def _structure_hook(*, ground_truth, hypothesis, **_): requires_success=True, ) def _line_metrics_hook(*, ground_truth, hypothesis, **_): - from picarones.measurements.line_metrics import compute_line_metrics + from picarones.evaluation.metrics.line_metrics import compute_line_metrics return compute_line_metrics(ground_truth, hypothesis).as_dict() @@ -206,7 +206,7 @@ def _line_metrics_hook(*, ground_truth, hypothesis, **_): requires_success=True, ) def _hallucination_hook(*, ground_truth, hypothesis, **_): - from picarones.measurements.hallucination import compute_hallucination_metrics + from picarones.evaluation.metrics.hallucination import compute_hallucination_metrics return compute_hallucination_metrics(ground_truth, hypothesis).as_dict() @@ -230,7 +230,7 @@ def _calibration_hook(*, ground_truth, ocr_result, **_): # résultat OCR (pour comparer un échec OCR à la qualité image). ) def _image_quality_hook(*, image_path, **_): - from picarones.measurements.image_quality import analyze_image_quality + from picarones.evaluation.metrics.image_quality import analyze_image_quality iq = analyze_image_quality(image_path) if iq.error is not None: return None @@ -294,7 +294,7 @@ def _readability_hook(*, ground_truth, hypothesis, corpus_lang, **_): profiles=_STANDARD_PROFILES, ) def _aggregate_confusion(doc_results: list) -> Optional[dict]: - from picarones.measurements.confusion import ( + from picarones.evaluation.metrics.confusion import ( ConfusionMatrix, aggregate_confusion_matrices, ) try: @@ -321,7 +321,7 @@ def _aggregate_confusion(doc_results: list) -> Optional[dict]: profiles=_STANDARD_PROFILES, ) def _aggregate_char_scores(doc_results: list) -> Optional[dict]: - from picarones.measurements.char_scores import ( + from picarones.evaluation.metrics.char_scores import ( DiacriticScore, LigatureScore, aggregate_diacritic_scores, @@ -351,7 +351,7 @@ def _aggregate_char_scores(doc_results: list) -> Optional[dict]: profiles=_STANDARD_PROFILES, ) def _aggregate_taxonomy(doc_results: list) -> Optional[dict]: - from picarones.measurements.taxonomy import TaxonomyResult, aggregate_taxonomy + from picarones.evaluation.metrics.taxonomy import TaxonomyResult, aggregate_taxonomy results = [ TaxonomyResult.from_dict(dr.taxonomy) for dr in doc_results @@ -368,7 +368,7 @@ def _aggregate_taxonomy(doc_results: list) -> Optional[dict]: profiles=_STANDARD_PROFILES, ) def _aggregate_structure(doc_results: list) -> Optional[dict]: - from picarones.measurements.structure import StructureResult, aggregate_structure + from picarones.evaluation.metrics.structure import StructureResult, aggregate_structure results = [ StructureResult.from_dict(dr.structure) for dr in doc_results @@ -385,7 +385,7 @@ def _aggregate_structure(doc_results: list) -> Optional[dict]: profiles=_STANDARD_PROFILES, ) def _aggregate_image_quality(doc_results: list) -> Optional[dict]: - from picarones.measurements.image_quality import ( + from picarones.evaluation.metrics.image_quality import ( ImageQualityResult, aggregate_image_quality, ) results = [ @@ -404,7 +404,7 @@ def _aggregate_image_quality(doc_results: list) -> Optional[dict]: profiles=_STANDARD_PROFILES, ) def _aggregate_line_metrics(doc_results: list) -> Optional[dict]: - from picarones.measurements.line_metrics import ( + from picarones.evaluation.metrics.line_metrics import ( LineMetrics, aggregate_line_metrics, ) results = [ @@ -423,7 +423,7 @@ def _aggregate_line_metrics(doc_results: list) -> Optional[dict]: profiles=_STANDARD_PROFILES, ) def _aggregate_hallucination(doc_results: list) -> Optional[dict]: - from picarones.measurements.hallucination import ( + from picarones.evaluation.metrics.hallucination import ( HallucinationMetrics, aggregate_hallucination_metrics, ) results = [ diff --git a/picarones/measurements/calibration.py b/picarones/measurements/calibration.py deleted file mode 100644 index 46e95453d9b83600dc36e09a882cd9541ed67536..0000000000000000000000000000000000000000 --- a/picarones/measurements/calibration.py +++ /dev/null @@ -1,10 +0,0 @@ -"""Re-export — Sprint A14-S10. Le contenu canonique vit dans -``picarones.evaluation.metrics.calibration``. - -L'ancien chemin ``picarones.measurements.calibration`` est conservé pour -ne casser aucun consommateur. Au S22, ce re-export disparaîtra. -""" - -from __future__ import annotations - -from picarones.evaluation.metrics.calibration import * # noqa: F401,F403 diff --git a/picarones/measurements/char_scores.py b/picarones/measurements/char_scores.py deleted file mode 100644 index 746eaa783db9a2987bf596e8a5b561a931637899..0000000000000000000000000000000000000000 --- a/picarones/measurements/char_scores.py +++ /dev/null @@ -1,34 +0,0 @@ -"""``picarones.measurements.char_scores`` — shim re-export (déprécié, suppression 2.0). - -Canonique : :mod:`picarones.evaluation.metrics.char_scores`. -""" - -from __future__ import annotations - -import warnings - -from picarones.evaluation.metrics.char_scores import ( # noqa: F401 - LIGATURE_TABLE, - DIACRITIC_MAP, - LigatureScore, - DiacriticScore, - compute_ligature_score, - compute_diacritic_score, - aggregate_ligature_scores, - aggregate_diacritic_scores, - _ALL_LIGATURES, - _SEQ_TO_LIGATURE, - _build_diacritic_map, - _ALL_DIACRITICS, - _LIGATURE_SET, - _check_char_at_context, -) - -warnings.warn( - "picarones.measurements.char_scores is deprecated and will be removed in 2.0. " - "Import from picarones.evaluation.metrics.char_scores instead.", - DeprecationWarning, - stacklevel=2, -) - -__all__ = ['LIGATURE_TABLE', 'DIACRITIC_MAP', 'LigatureScore', 'DiacriticScore', 'compute_ligature_score', 'compute_diacritic_score', 'aggregate_ligature_scores', 'aggregate_diacritic_scores'] diff --git a/picarones/measurements/confusion.py b/picarones/measurements/confusion.py deleted file mode 100644 index ecb400b1649f2ab3aaf81543ce8d27e53dcf64cd..0000000000000000000000000000000000000000 --- a/picarones/measurements/confusion.py +++ /dev/null @@ -1,10 +0,0 @@ -"""Re-export — Sprint A14-S10. Le contenu canonique vit dans -``picarones.evaluation.metrics.confusion``. - -L'ancien chemin ``picarones.measurements.confusion`` est conservé pour -ne casser aucun consommateur. Au S22, ce re-export disparaîtra. -""" - -from __future__ import annotations - -from picarones.evaluation.metrics.confusion import * # noqa: F401,F403 diff --git a/picarones/measurements/cost_projection.py b/picarones/measurements/cost_projection.py deleted file mode 100644 index b36cea483c2244d08079c090c135b1e73b0fa3f2..0000000000000000000000000000000000000000 --- a/picarones/measurements/cost_projection.py +++ /dev/null @@ -1,26 +0,0 @@ -"""``picarones.measurements.cost_projection`` — shim re-export (déprécié, suppression 2.0). - -Canonique : :mod:`picarones.evaluation.metrics.cost_projection`. -""" - -from __future__ import annotations - -import warnings - -from picarones.evaluation.metrics.cost_projection import ( # noqa: F401 - ProjectedCost, - project_cost_total, - project_co2_total, - project_engine, - project_all_engines, - cost_gap_table, -) - -warnings.warn( - "picarones.measurements.cost_projection is deprecated and will be removed in 2.0. " - "Import from picarones.evaluation.metrics.cost_projection instead.", - DeprecationWarning, - stacklevel=2, -) - -__all__ = ['ProjectedCost', 'project_cost_total', 'project_co2_total', 'project_engine', 'project_all_engines', 'cost_gap_table'] diff --git a/picarones/measurements/difficulty.py b/picarones/measurements/difficulty.py deleted file mode 100644 index d28b4267bf1cf42473751df98a38f0c63bc2ed99..0000000000000000000000000000000000000000 --- a/picarones/measurements/difficulty.py +++ /dev/null @@ -1,30 +0,0 @@ -"""``picarones.measurements.difficulty`` — shim re-export (déprécié, suppression 2.0). - -Canonique : :mod:`picarones.evaluation.metrics.difficulty`. -""" - -from __future__ import annotations - -import warnings - -from picarones.evaluation.metrics.difficulty import ( # noqa: F401 - DifficultyScore, - compute_difficulty_score, - compute_all_difficulties, - difficulty_label, - _W_VARIANCE, - _W_QUALITY, - _W_DENSITY, - _SPECIAL_CHARS_RE, - _special_char_density, - _variance, -) - -warnings.warn( - "picarones.measurements.difficulty is deprecated and will be removed in 2.0. " - "Import from picarones.evaluation.metrics.difficulty instead.", - DeprecationWarning, - stacklevel=2, -) - -__all__ = ['DifficultyScore', 'compute_difficulty_score', 'compute_all_difficulties', 'difficulty_label'] diff --git a/picarones/measurements/equivalence_profile.py b/picarones/measurements/equivalence_profile.py index cb8c001f0bb01baf48aac621b482e2cec4872701..38427c6a4f8a581db1e3d57d6c4f557faf61938a 100644 --- a/picarones/measurements/equivalence_profile.py +++ b/picarones/measurements/equivalence_profile.py @@ -42,7 +42,7 @@ import logging from dataclasses import dataclass from typing import Iterable, Optional -from picarones.measurements.normalization import ( +from picarones.evaluation.metrics.normalization import ( DIPLOMATIC_EN_EARLY_MODERN, DIPLOMATIC_FR_EARLY_MODERN, DIPLOMATIC_LATIN_MEDIEVAL, diff --git a/picarones/measurements/error_absorption.py b/picarones/measurements/error_absorption.py deleted file mode 100644 index dc67ac228543843ea0a67527022c0f100d2c960e..0000000000000000000000000000000000000000 --- a/picarones/measurements/error_absorption.py +++ /dev/null @@ -1,10 +0,0 @@ -"""Re-export — Sprint A14-S10. Le contenu canonique vit dans -``picarones.evaluation.metrics.error_absorption``. - -L'ancien chemin ``picarones.measurements.error_absorption`` est conservé pour -ne casser aucun consommateur. Au S22, ce re-export disparaîtra. -""" - -from __future__ import annotations - -from picarones.evaluation.metrics.error_absorption import * # noqa: F401,F403 diff --git a/picarones/measurements/hallucination.py b/picarones/measurements/hallucination.py deleted file mode 100644 index aebd1c1fbaf2c7a83cfce8291aa320911a20ff73..0000000000000000000000000000000000000000 --- a/picarones/measurements/hallucination.py +++ /dev/null @@ -1,10 +0,0 @@ -"""Re-export — Sprint A14-S10. Le contenu canonique vit dans -``picarones.evaluation.metrics.hallucination``. - -L'ancien chemin ``picarones.measurements.hallucination`` est conservé -pour ne casser aucun consommateur. Au S22, ce re-export disparaîtra. -""" - -from __future__ import annotations - -from picarones.evaluation.metrics.hallucination import * # noqa: F401,F403 diff --git a/picarones/measurements/image_predictive.py b/picarones/measurements/image_predictive.py deleted file mode 100644 index 38cc40f0eac6e8b84191837f8b3100770a77380c..0000000000000000000000000000000000000000 --- a/picarones/measurements/image_predictive.py +++ /dev/null @@ -1,10 +0,0 @@ -"""Re-export — Sprint A14-S10. Le contenu canonique vit dans -``picarones.evaluation.metrics.image_predictive``. - -L'ancien chemin ``picarones.measurements.image_predictive`` est conservé pour -ne casser aucun consommateur. Au S22, ce re-export disparaîtra. -""" - -from __future__ import annotations - -from picarones.evaluation.metrics.image_predictive import * # noqa: F401,F403 diff --git a/picarones/measurements/image_quality.py b/picarones/measurements/image_quality.py deleted file mode 100644 index 498594dd2d08b5e2a0b8667491be3b1629db6c67..0000000000000000000000000000000000000000 --- a/picarones/measurements/image_quality.py +++ /dev/null @@ -1,14 +0,0 @@ -"""Re-export — Sprint A14-S10. Le contenu canonique vit dans -``picarones.evaluation.metrics.image_quality``. - -L'ancien chemin ``picarones.measurements.image_quality`` est conservé -pour ne casser aucun consommateur. Au S22, ce re-export disparaîtra. - -Ré-expose explicitement ``_global_quality_score`` (symbole privé -utilisé downstream). -""" - -from __future__ import annotations - -from picarones.evaluation.metrics.image_quality import * # noqa: F401,F403 -from picarones.evaluation.metrics.image_quality import _global_quality_score # noqa: F401 diff --git a/picarones/measurements/incremental_comparison.py b/picarones/measurements/incremental_comparison.py deleted file mode 100644 index 8b5a4a2bf806d7d85ea3c78c1f764c9bed897567..0000000000000000000000000000000000000000 --- a/picarones/measurements/incremental_comparison.py +++ /dev/null @@ -1,10 +0,0 @@ -"""Re-export — Sprint A14-S10. Le contenu canonique vit dans -``picarones.evaluation.metrics.incremental_comparison``. - -L'ancien chemin ``picarones.measurements.incremental_comparison`` est conservé pour -ne casser aucun consommateur. Au S22, ce re-export disparaîtra. -""" - -from __future__ import annotations - -from picarones.evaluation.metrics.incremental_comparison import * # noqa: F401,F403 diff --git a/picarones/measurements/inter_engine.py b/picarones/measurements/inter_engine.py deleted file mode 100644 index 37882d4c73a1699193356248f8e34a37dc6fdb8d..0000000000000000000000000000000000000000 --- a/picarones/measurements/inter_engine.py +++ /dev/null @@ -1,10 +0,0 @@ -"""Re-export — Sprint A14-S10. Le contenu canonique vit dans -``picarones.evaluation.metrics.inter_engine``. - -L'ancien chemin ``picarones.measurements.inter_engine`` est conservé pour -ne casser aucun consommateur. Au S22, ce re-export disparaîtra. -""" - -from __future__ import annotations - -from picarones.evaluation.metrics.inter_engine import * # noqa: F401,F403 diff --git a/picarones/measurements/layout.py b/picarones/measurements/layout.py deleted file mode 100644 index 557782cf06f9ae16d5d6374397029f726644c469..0000000000000000000000000000000000000000 --- a/picarones/measurements/layout.py +++ /dev/null @@ -1,14 +0,0 @@ -"""Re-export — Sprint A14-S10. Le contenu canonique vit dans -``picarones.evaluation.metrics.layout``. - -L'ancien chemin ``picarones.measurements.layout`` est conservé pour -ne casser aucun consommateur. Au S22, ce re-export disparaîtra. - -Ré-expose explicitement le symbole privé ``_iou_bbox`` qu'au moins -un test importe directement. -""" - -from __future__ import annotations - -from picarones.evaluation.metrics.layout import * # noqa: F401,F403 -from picarones.evaluation.metrics.layout import _iou_bbox # noqa: F401 diff --git a/picarones/measurements/levers.py b/picarones/measurements/levers.py deleted file mode 100644 index b068c809a10cf35d4bd064695e98a20d031b0170..0000000000000000000000000000000000000000 --- a/picarones/measurements/levers.py +++ /dev/null @@ -1,10 +0,0 @@ -"""Re-export — Sprint A14-S10. Le contenu canonique vit dans -``picarones.evaluation.metrics.levers``. - -L'ancien chemin ``picarones.measurements.levers`` est conservé pour -ne casser aucun consommateur. Au S22, ce re-export disparaîtra. -""" - -from __future__ import annotations - -from picarones.evaluation.metrics.levers import * # noqa: F401,F403 diff --git a/picarones/measurements/lexical_modernization.py b/picarones/measurements/lexical_modernization.py deleted file mode 100644 index 651da4ef65c954db9d675c9285f5f91435455489..0000000000000000000000000000000000000000 --- a/picarones/measurements/lexical_modernization.py +++ /dev/null @@ -1,10 +0,0 @@ -"""Re-export — Sprint A14-S10. Le contenu canonique vit dans -``picarones.evaluation.metrics.lexical_modernization``. - -L'ancien chemin ``picarones.measurements.lexical_modernization`` est conservé pour -ne casser aucun consommateur. Au S22, ce re-export disparaîtra. -""" - -from __future__ import annotations - -from picarones.evaluation.metrics.lexical_modernization import * # noqa: F401,F403 diff --git a/picarones/measurements/line_metrics.py b/picarones/measurements/line_metrics.py deleted file mode 100644 index 53ca9108dae089384ad0627a6ef84fe99bd87a10..0000000000000000000000000000000000000000 --- a/picarones/measurements/line_metrics.py +++ /dev/null @@ -1,10 +0,0 @@ -"""Re-export — Sprint A14-S10. Le contenu canonique vit dans -``picarones.evaluation.metrics.line_metrics``. - -L'ancien chemin ``picarones.measurements.line_metrics`` est conservé pour -ne casser aucun consommateur. Au S22, ce re-export disparaîtra. -""" - -from __future__ import annotations - -from picarones.evaluation.metrics.line_metrics import * # noqa: F401,F403 diff --git a/picarones/measurements/longitudinal.py b/picarones/measurements/longitudinal.py deleted file mode 100644 index 5c329343f756b64f797bc87724011b938f56c7db..0000000000000000000000000000000000000000 --- a/picarones/measurements/longitudinal.py +++ /dev/null @@ -1,10 +0,0 @@ -"""Re-export — Sprint A14-S10. Le contenu canonique vit dans -``picarones.evaluation.metrics.longitudinal``. - -L'ancien chemin ``picarones.measurements.longitudinal`` est conservé pour -ne casser aucun consommateur. Au S22, ce re-export disparaîtra. -""" - -from __future__ import annotations - -from picarones.evaluation.metrics.longitudinal import * # noqa: F401,F403 diff --git a/picarones/measurements/marginal_cost.py b/picarones/measurements/marginal_cost.py deleted file mode 100644 index b6ed75d8d1fadff4531a04d9eef1935b8e045b9c..0000000000000000000000000000000000000000 --- a/picarones/measurements/marginal_cost.py +++ /dev/null @@ -1,10 +0,0 @@ -"""Re-export — Sprint A14-S10. Le contenu canonique vit dans -``picarones.evaluation.metrics.marginal_cost``. - -L'ancien chemin ``picarones.measurements.marginal_cost`` est conservé pour -ne casser aucun consommateur. Au S22, ce re-export disparaîtra. -""" - -from __future__ import annotations - -from picarones.evaluation.metrics.marginal_cost import * # noqa: F401,F403 diff --git a/picarones/measurements/metrics.py b/picarones/measurements/metrics.py index 144e2bcce92dc2592746d65d43d7fe0d5652312c..3c39f76e8fd8dceb5159e358d4742f71fe044fda 100644 --- a/picarones/measurements/metrics.py +++ b/picarones/measurements/metrics.py @@ -155,7 +155,7 @@ def compute_metrics( cer_diplomatic: Optional[float] = None diplomatic_profile_name: Optional[str] = None try: - from picarones.measurements.normalization import DEFAULT_DIPLOMATIC_PROFILE + from picarones.evaluation.metrics.normalization import DEFAULT_DIPLOMATIC_PROFILE profile = normalization_profile or DEFAULT_DIPLOMATIC_PROFILE ref_diplo = profile.normalize(reference) hyp_diplo = profile.normalize(hypothesis) @@ -197,4 +197,4 @@ __all__ = ["MetricsResult", "aggregate_metrics", "compute_metrics"] # Import paresseux pour éviter les imports circulaires from typing import TYPE_CHECKING if TYPE_CHECKING: - from picarones.measurements.normalization import NormalizationProfile + from picarones.evaluation.metrics.normalization import NormalizationProfile diff --git a/picarones/measurements/module_policy.py b/picarones/measurements/module_policy.py deleted file mode 100644 index 8b4cf0526186668b1339e4cd2dd2b36b6a2ee9bf..0000000000000000000000000000000000000000 --- a/picarones/measurements/module_policy.py +++ /dev/null @@ -1,10 +0,0 @@ -"""Re-export — Sprint A14-S10. Le contenu canonique vit dans -``picarones.evaluation.metrics.module_policy``. - -L'ancien chemin ``picarones.measurements.module_policy`` est conservé pour -ne casser aucun consommateur. Au S22, ce re-export disparaîtra. -""" - -from __future__ import annotations - -from picarones.evaluation.metrics.module_policy import * # noqa: F401,F403 diff --git a/picarones/measurements/ner_backends.py b/picarones/measurements/ner_backends.py deleted file mode 100644 index 53edf6e873463efa9da4a786f6ccfd0703a190a6..0000000000000000000000000000000000000000 --- a/picarones/measurements/ner_backends.py +++ /dev/null @@ -1,25 +0,0 @@ -"""``picarones.measurements.ner_backends`` — shim re-export (déprécié, suppression 2.0). - -Canonique : :mod:`picarones.evaluation.metrics.ner_backends`. -""" - -from __future__ import annotations - -import warnings - -from picarones.evaluation.metrics.ner_backends import ( # noqa: F401 - EntityExtractor, - SpacyEntityExtractor, - SPACY_PROFILES, - get_extractor, - is_spacy_available, -) - -warnings.warn( - "picarones.measurements.ner_backends is deprecated and will be removed in 2.0. " - "Import from picarones.evaluation.metrics.ner_backends instead.", - DeprecationWarning, - stacklevel=2, -) - -__all__ = ['EntityExtractor', 'SpacyEntityExtractor', 'SPACY_PROFILES', 'get_extractor', 'is_spacy_available'] diff --git a/picarones/measurements/normalization.py b/picarones/measurements/normalization.py deleted file mode 100644 index b1b3186c69d447d14e77b63ae12eabcb9a88bfd9..0000000000000000000000000000000000000000 --- a/picarones/measurements/normalization.py +++ /dev/null @@ -1,33 +0,0 @@ -"""``picarones.measurements.normalization`` — shim re-export (déprécié, suppression 2.0). - -Canonique : :mod:`picarones.evaluation.metrics.normalization`. -""" - -from __future__ import annotations - -import warnings - -from picarones.evaluation.metrics.normalization import ( # noqa: F401 - NormalizationProfile, - DIPLOMATIC_FR_MEDIEVAL, - DIPLOMATIC_FR_EARLY_MODERN, - DIPLOMATIC_LATIN_MEDIEVAL, - DIPLOMATIC_MINIMAL, - DIPLOMATIC_EN_EARLY_MODERN, - DIPLOMATIC_EN_MEDIEVAL, - DIPLOMATIC_EN_SECRETARY, - NORMALIZATION_PROFILES, - DEFAULT_DIPLOMATIC_PROFILE, - get_builtin_profile, - _parse_exclude_chars, - _apply_diplomatic_table, -) - -warnings.warn( - "picarones.measurements.normalization is deprecated and will be removed in 2.0. " - "Import from picarones.evaluation.metrics.normalization instead.", - DeprecationWarning, - stacklevel=2, -) - -__all__ = ['NormalizationProfile', 'DIPLOMATIC_FR_MEDIEVAL', 'DIPLOMATIC_FR_EARLY_MODERN', 'DIPLOMATIC_LATIN_MEDIEVAL', 'DIPLOMATIC_MINIMAL', 'DIPLOMATIC_EN_EARLY_MODERN', 'DIPLOMATIC_EN_MEDIEVAL', 'DIPLOMATIC_EN_SECRETARY', 'NORMALIZATION_PROFILES', 'DEFAULT_DIPLOMATIC_PROFILE', 'get_builtin_profile', '_parse_exclude_chars', '_apply_diplomatic_table'] diff --git a/picarones/measurements/numerical_sequences.py b/picarones/measurements/numerical_sequences.py deleted file mode 100644 index a51260ecd34630be0188e3bd72bc4ead0da53cda..0000000000000000000000000000000000000000 --- a/picarones/measurements/numerical_sequences.py +++ /dev/null @@ -1,18 +0,0 @@ -"""``picarones.measurements.numerical_sequences`` — shim re-export (déprécié, suppression 2.0). - -Canonique : :mod:`picarones.evaluation.metrics.numerical_sequences`. -Phase 5.C.batch7 du retrait du legacy. -""" - -from __future__ import annotations - -import warnings - -from picarones.evaluation.metrics.numerical_sequences import * # noqa: F401, F403 - -warnings.warn( - "picarones.measurements.numerical_sequences is deprecated and will be removed in 2.0. " - "Import from picarones.evaluation.metrics.numerical_sequences instead.", - DeprecationWarning, - stacklevel=2, -) diff --git a/picarones/measurements/pricing.py b/picarones/measurements/pricing.py deleted file mode 100644 index 55ca9de08de86376c5b7756b553054438cec3e57..0000000000000000000000000000000000000000 --- a/picarones/measurements/pricing.py +++ /dev/null @@ -1,15 +0,0 @@ -"""Re-export — Sprint A14-S10. Le contenu canonique vit dans -``picarones.evaluation.metrics.pricing``. - -L'ancien chemin ``picarones.measurements.pricing`` est conservé pour -ne casser aucun consommateur. Au S22, ce re-export disparaîtra. - -Ce module ré-expose **explicitement** le symbole privé -``_DEFAULT_PRICING_PATH`` qu'au moins un consommateur importe -directement (cf. tests). -""" - -from __future__ import annotations - -from picarones.evaluation.metrics.pricing import * # noqa: F401,F403 -from picarones.evaluation.metrics.pricing import _DEFAULT_PRICING_PATH # noqa: F401 diff --git a/picarones/measurements/rare_tokens.py b/picarones/measurements/rare_tokens.py deleted file mode 100644 index ed8fa830a86b37149f0117c00db7a12e1bc8f5c4..0000000000000000000000000000000000000000 --- a/picarones/measurements/rare_tokens.py +++ /dev/null @@ -1,10 +0,0 @@ -"""Re-export — Sprint A14-S10. Le contenu canonique vit dans -``picarones.evaluation.metrics.rare_tokens``. - -L'ancien chemin ``picarones.measurements.rare_tokens`` est conservé pour -ne casser aucun consommateur. Au S22, ce re-export disparaîtra. -""" - -from __future__ import annotations - -from picarones.evaluation.metrics.rare_tokens import * # noqa: F401,F403 diff --git a/picarones/measurements/robustness_projection.py b/picarones/measurements/robustness_projection.py deleted file mode 100644 index d8133192c062b65100db1298ec7339671b2bc48e..0000000000000000000000000000000000000000 --- a/picarones/measurements/robustness_projection.py +++ /dev/null @@ -1,18 +0,0 @@ -"""Re-export — Sprint A14-S10. Le contenu canonique vit dans -``picarones.evaluation.metrics.robustness_projection``. - -L'ancien chemin ``picarones.measurements.robustness_projection`` est -conservé pour ne casser aucun consommateur. Au S22, ce re-export -disparaîtra. - -Ré-expose explicitement ``_extract_quality_value`` et -``_interpolate_cer`` (symboles privés utilisés downstream). -""" - -from __future__ import annotations - -from picarones.evaluation.metrics.robustness_projection import * # noqa: F401,F403 -from picarones.evaluation.metrics.robustness_projection import ( # noqa: F401 - _extract_quality_value, - _interpolate_cer, -) diff --git a/picarones/measurements/roman_numerals.py b/picarones/measurements/roman_numerals.py deleted file mode 100644 index 4351e2f11603be515f3513b586195bd23cbf0cc1..0000000000000000000000000000000000000000 --- a/picarones/measurements/roman_numerals.py +++ /dev/null @@ -1,18 +0,0 @@ -"""``picarones.measurements.roman_numerals`` — shim re-export (déprécié, suppression 2.0). - -Canonique : :mod:`picarones.evaluation.metrics.roman_numerals`. -Phase 5.C.batch7 du retrait du legacy. -""" - -from __future__ import annotations - -import warnings - -from picarones.evaluation.metrics.roman_numerals import * # noqa: F401, F403 - -warnings.warn( - "picarones.measurements.roman_numerals is deprecated and will be removed in 2.0. " - "Import from picarones.evaluation.metrics.roman_numerals instead.", - DeprecationWarning, - stacklevel=2, -) diff --git a/picarones/measurements/runner/orchestration.py b/picarones/measurements/runner/orchestration.py index 18020cecf767622e4899a5a5ee28ddface23eb71..6ba486affde55fa673e6c9189880620936af07a8 100644 --- a/picarones/measurements/runner/orchestration.py +++ b/picarones/measurements/runner/orchestration.py @@ -151,7 +151,7 @@ def run_benchmark( # éviter de re-résoudre N fois côté workers. norm_profile_obj = None if normalization_profile is not None: - from picarones.measurements.normalization import get_builtin_profile + from picarones.evaluation.metrics.normalization import get_builtin_profile norm_profile_obj = get_builtin_profile(normalization_profile) def _is_cancelled() -> bool: @@ -435,7 +435,7 @@ def run_benchmark( inter_engine_payload: Optional[dict] = None if len(engine_reports) >= 2: try: - from picarones.measurements.inter_engine import compute_inter_engine_analysis + from picarones.evaluation.metrics.inter_engine import compute_inter_engine_analysis taxonomy_distros = { report.engine_name: ( diff --git a/picarones/measurements/specialization.py b/picarones/measurements/specialization.py deleted file mode 100644 index f4ff3a672181feff5bdbe8d3410e5a61c9243b54..0000000000000000000000000000000000000000 --- a/picarones/measurements/specialization.py +++ /dev/null @@ -1,25 +0,0 @@ -"""``picarones.measurements.specialization`` — shim re-export (déprécié, suppression 2.0). - -Canonique : :mod:`picarones.evaluation.metrics.specialization`. -""" - -from __future__ import annotations - -import warnings - -from picarones.evaluation.metrics.specialization import ( # noqa: F401 - DEFAULT_THRESHOLDS, - compute_specialization_score, - classify_specialization, - compute_specialization_matrix, - top_specialized_pairs, -) - -warnings.warn( - "picarones.measurements.specialization is deprecated and will be removed in 2.0. " - "Import from picarones.evaluation.metrics.specialization instead.", - DeprecationWarning, - stacklevel=2, -) - -__all__ = ['DEFAULT_THRESHOLDS', 'compute_specialization_score', 'classify_specialization', 'compute_specialization_matrix', 'top_specialized_pairs'] diff --git a/picarones/measurements/structure.py b/picarones/measurements/structure.py deleted file mode 100644 index a793aea8f16bdcfa639f72a1820fe1ae7098b8c8..0000000000000000000000000000000000000000 --- a/picarones/measurements/structure.py +++ /dev/null @@ -1,26 +0,0 @@ -"""``picarones.measurements.structure`` — shim re-export (déprécié, suppression 2.0). - -Canonique : :mod:`picarones.evaluation.metrics.structure`. -""" - -from __future__ import annotations - -import warnings - -from picarones.evaluation.metrics.structure import ( # noqa: F401 - StructureResult, - analyze_structure, - aggregate_structure, - _count_line_changes, - _reading_order_score, - _paragraph_conservation_score, -) - -warnings.warn( - "picarones.measurements.structure is deprecated and will be removed in 2.0. " - "Import from picarones.evaluation.metrics.structure instead.", - DeprecationWarning, - stacklevel=2, -) - -__all__ = ['StructureResult', 'analyze_structure', 'aggregate_structure'] diff --git a/picarones/measurements/taxonomy.py b/picarones/measurements/taxonomy.py deleted file mode 100644 index f90947d0eea1c0e5900aa11d25387874e18db0ad..0000000000000000000000000000000000000000 --- a/picarones/measurements/taxonomy.py +++ /dev/null @@ -1,33 +0,0 @@ -"""``picarones.measurements.taxonomy`` — shim re-export (déprécié, suppression 2.0). - -Canonique : :mod:`picarones.evaluation.metrics.taxonomy`. -""" - -from __future__ import annotations - -import warnings - -from picarones.evaluation.metrics.taxonomy import ( # noqa: F401 - VISUAL_CONFUSIONS, - TaxonomyResult, - ERROR_CLASSES, - classify_errors, - aggregate_taxonomy, - _VISUAL_PAIRS, - _LATIN_BASIC, - _classify_word_error, - _is_ligature_error, - _is_abbreviation_error, - _is_diacritic_error, - _is_visual_confusion, - _is_oov_word, -) - -warnings.warn( - "picarones.measurements.taxonomy is deprecated and will be removed in 2.0. " - "Import from picarones.evaluation.metrics.taxonomy instead.", - DeprecationWarning, - stacklevel=2, -) - -__all__ = ['VISUAL_CONFUSIONS', 'TaxonomyResult', 'ERROR_CLASSES', 'classify_errors', 'aggregate_taxonomy'] diff --git a/picarones/measurements/taxonomy_comparison.py b/picarones/measurements/taxonomy_comparison.py deleted file mode 100644 index 0e276289cd8145c1e819ecbc94ca823a5b284002..0000000000000000000000000000000000000000 --- a/picarones/measurements/taxonomy_comparison.py +++ /dev/null @@ -1,10 +0,0 @@ -"""Re-export — Sprint A14-S10. Le contenu canonique vit dans -``picarones.evaluation.metrics.taxonomy_comparison``. - -L'ancien chemin ``picarones.measurements.taxonomy_comparison`` est conservé pour -ne casser aucun consommateur. Au S22, ce re-export disparaîtra. -""" - -from __future__ import annotations - -from picarones.evaluation.metrics.taxonomy_comparison import * # noqa: F401,F403 diff --git a/picarones/measurements/taxonomy_cooccurrence.py b/picarones/measurements/taxonomy_cooccurrence.py deleted file mode 100644 index 9636fe5e595c967a452ca1121b4adc32eb5adc12..0000000000000000000000000000000000000000 --- a/picarones/measurements/taxonomy_cooccurrence.py +++ /dev/null @@ -1,10 +0,0 @@ -"""Re-export — Sprint A14-S10. Le contenu canonique vit dans -``picarones.evaluation.metrics.taxonomy_cooccurrence``. - -L'ancien chemin ``picarones.measurements.taxonomy_cooccurrence`` est conservé pour -ne casser aucun consommateur. Au S22, ce re-export disparaîtra. -""" - -from __future__ import annotations - -from picarones.evaluation.metrics.taxonomy_cooccurrence import * # noqa: F401,F403 diff --git a/picarones/measurements/taxonomy_intra_doc.py b/picarones/measurements/taxonomy_intra_doc.py deleted file mode 100644 index dadd87f2425bb5f079ef8882ffe51f868b7d8f72..0000000000000000000000000000000000000000 --- a/picarones/measurements/taxonomy_intra_doc.py +++ /dev/null @@ -1,23 +0,0 @@ -"""``picarones.measurements.taxonomy_intra_doc`` — shim re-export (déprécié, suppression 2.0). - -Canonique : :mod:`picarones.evaluation.metrics.taxonomy_intra_doc`. -""" - -from __future__ import annotations - -import warnings - -from picarones.evaluation.metrics.taxonomy_intra_doc import ( # noqa: F401 - compute_taxonomy_position_heatmap, - _classify_word_pair, - _bin_for_position, -) - -warnings.warn( - "picarones.measurements.taxonomy_intra_doc is deprecated and will be removed in 2.0. " - "Import from picarones.evaluation.metrics.taxonomy_intra_doc instead.", - DeprecationWarning, - stacklevel=2, -) - -__all__ = ['compute_taxonomy_position_heatmap'] diff --git a/picarones/measurements/throughput.py b/picarones/measurements/throughput.py deleted file mode 100644 index ab95080b653c0130f90c4b745f7ef069e153970c..0000000000000000000000000000000000000000 --- a/picarones/measurements/throughput.py +++ /dev/null @@ -1,10 +0,0 @@ -"""Re-export — Sprint A14-S10. Le contenu canonique vit dans -``picarones.evaluation.metrics.throughput``. - -L'ancien chemin ``picarones.measurements.throughput`` est conservé pour -ne casser aucun consommateur. Au S22, ce re-export disparaîtra. -""" - -from __future__ import annotations - -from picarones.evaluation.metrics.throughput import * # noqa: F401,F403 diff --git a/picarones/measurements/worst_lines.py b/picarones/measurements/worst_lines.py deleted file mode 100644 index de594193011ee8f3cca630af249404fef9164cde..0000000000000000000000000000000000000000 --- a/picarones/measurements/worst_lines.py +++ /dev/null @@ -1,10 +0,0 @@ -"""Re-export — Sprint A14-S10. Le contenu canonique vit dans -``picarones.evaluation.metrics.worst_lines``. - -L'ancien chemin ``picarones.measurements.worst_lines`` est conservé pour -ne casser aucun consommateur. Au S22, ce re-export disparaîtra. -""" - -from __future__ import annotations - -from picarones.evaluation.metrics.worst_lines import * # noqa: F401,F403 diff --git a/picarones/reports_v2/html/renderers/error_absorption.py b/picarones/reports_v2/html/renderers/error_absorption.py index a4aee3ce77c4caa6fc173862cbf436915b7eeb27..5177f8da9246713db7cac291bf2c8f6cd184c352 100644 --- a/picarones/reports_v2/html/renderers/error_absorption.py +++ b/picarones/reports_v2/html/renderers/error_absorption.py @@ -31,7 +31,7 @@ l'utilisateur depuis son benchmark de pipeline composée : .. code-block:: python - from picarones.measurements.error_absorption import ( + from picarones.evaluation.metrics.error_absorption import ( compute_error_absorption, aggregate_error_absorption, ) from picarones.reports_v2.html.renderers.error_absorption import ( diff --git a/picarones/reports_v2/html/renderers/image_predictive.py b/picarones/reports_v2/html/renderers/image_predictive.py index 4e24ea902b5e784c3abcf65203fdb071dc8d25bc..aabd9d305e996cd5e6f87c0a27c6c67e5d2dd3b1 100644 --- a/picarones/reports_v2/html/renderers/image_predictive.py +++ b/picarones/reports_v2/html/renderers/image_predictive.py @@ -27,7 +27,7 @@ Module pur — l'utilisateur compose : .. code-block:: python - from picarones.measurements.image_predictive import aggregate_corpus_predictive + from picarones.evaluation.metrics.image_predictive import aggregate_corpus_predictive from picarones.reports_v2.html.renderers.image_predictive import ( build_image_predictive_html, ) diff --git a/picarones/reports_v2/html/renderers/incremental_comparison.py b/picarones/reports_v2/html/renderers/incremental_comparison.py index 256c225d27f84199e813eb0565f478848483e4b2..cce7a00d75096881315df56e6b4baeb14679be70 100644 --- a/picarones/reports_v2/html/renderers/incremental_comparison.py +++ b/picarones/reports_v2/html/renderers/incremental_comparison.py @@ -25,7 +25,7 @@ Module pur — l'utilisateur compose : .. code-block:: python - from picarones.measurements.incremental_comparison import ( + from picarones.evaluation.metrics.incremental_comparison import ( PipelineRun, compare_isolated_effect, ) from picarones.reports_v2.html.renderers.incremental_comparison import ( diff --git a/picarones/reports_v2/html/renderers/longitudinal.py b/picarones/reports_v2/html/renderers/longitudinal.py index ae1217c273f7f5c19f9b42e566b193029d892cbb..ca565ee3579a23a5520ac0fd3519575ddaa6555d 100644 --- a/picarones/reports_v2/html/renderers/longitudinal.py +++ b/picarones/reports_v2/html/renderers/longitudinal.py @@ -25,7 +25,7 @@ Module pur — l'utilisateur compose : .. code-block:: python from picarones.measurements.history import BenchmarkHistory - from picarones.measurements.longitudinal import compute_corpus_longitudinal + from picarones.evaluation.metrics.longitudinal import compute_corpus_longitudinal from picarones.reports_v2.html.renderers.longitudinal import build_longitudinal_html hist = BenchmarkHistory(db_path) diff --git a/picarones/reports_v2/html/renderers/module_audit.py b/picarones/reports_v2/html/renderers/module_audit.py index a1667c42af16e018cdda328c415c74282a338d3b..3e1d6c8c0d45c88763c7a7df3deae542e707c43c 100644 --- a/picarones/reports_v2/html/renderers/module_audit.py +++ b/picarones/reports_v2/html/renderers/module_audit.py @@ -30,7 +30,7 @@ Module pur — l'utilisateur compose la liste depuis sa .. code-block:: python - from picarones.measurements.module_policy import audit_module + from picarones.evaluation.metrics.module_policy import audit_module from picarones.reports_v2.html.renderers.module_audit import build_module_audit_html audits = [] diff --git a/picarones/reports_v2/html/renderers/robustness_projection.py b/picarones/reports_v2/html/renderers/robustness_projection.py index 0a47df57717a45ba869eea34167dc7c569ff3b2c..c314d7963bfa01e4ed8a5235f67c09d17e15bf8f 100644 --- a/picarones/reports_v2/html/renderers/robustness_projection.py +++ b/picarones/reports_v2/html/renderers/robustness_projection.py @@ -21,7 +21,7 @@ l'utilisateur compose : .. code-block:: python from picarones.measurements.robustness import analyze_robustness - from picarones.measurements.robustness_projection import ( + from picarones.evaluation.metrics.robustness_projection import ( project_robustness_on_corpus, aggregate_projection_per_engine, ) diff --git a/picarones/reports_v2/html/renderers/throughput.py b/picarones/reports_v2/html/renderers/throughput.py index 1e4390007794ef2de9183a0429b659f9020f589b..87ebe6390bc0e5f851806485f62d20750d1a68e2 100644 --- a/picarones/reports_v2/html/renderers/throughput.py +++ b/picarones/reports_v2/html/renderers/throughput.py @@ -26,7 +26,7 @@ Cette vue est un **module pur** — l'utilisateur compose : .. code-block:: python - from picarones.measurements.throughput import ( + from picarones.evaluation.metrics.throughput import ( aggregate_effective_throughput, ) from picarones.reports_v2.html.renderers.throughput import ( diff --git a/picarones/web/benchmark_utils.py b/picarones/web/benchmark_utils.py index f9855d7b15ece5bff35986239da10d3e2581f943..0bfd66a955bbb9635cb64d97dda02933495e40b7 100644 --- a/picarones/web/benchmark_utils.py +++ b/picarones/web/benchmark_utils.py @@ -208,7 +208,7 @@ def run_benchmark_thread_v2(job: BenchmarkJob, req: BenchmarkRunRequest) -> None "total": total_steps, }) - from picarones.measurements.normalization import _parse_exclude_chars + from picarones.evaluation.metrics.normalization import _parse_exclude_chars char_excl = _parse_exclude_chars(req.char_exclude) if req.char_exclude else None result = run_benchmark( @@ -316,7 +316,7 @@ def run_benchmark_thread(job: BenchmarkJob, req: BenchmarkRequest) -> None: "total": total_steps, }) - from picarones.measurements.normalization import _parse_exclude_chars + from picarones.evaluation.metrics.normalization import _parse_exclude_chars char_excl = _parse_exclude_chars(req.char_exclude) if req.char_exclude else None result = run_benchmark( diff --git a/picarones/web/routers/normalization.py b/picarones/web/routers/normalization.py index bb802dfeadb58ea485a448403f9f6e6ef7ae0cb2..4f72d5352bbf7948f4eeddc37cc817e498e0eab0 100644 --- a/picarones/web/routers/normalization.py +++ b/picarones/web/routers/normalization.py @@ -10,7 +10,7 @@ router = APIRouter() @router.get("/api/normalization/profiles") async def api_normalization_profiles() -> dict: """Liste les profils de normalisation disponibles avec leurs caractéristiques.""" - from picarones.measurements.normalization import NORMALIZATION_PROFILES + from picarones.evaluation.metrics.normalization import NORMALIZATION_PROFILES profiles = [ { diff --git a/tests/architecture/test_doc_paths.py b/tests/architecture/test_doc_paths.py index 77bd5b268a8574b3ad77382824c07d5eb4aded13..63f3cd5ceadec3e3a07101449cb607d4375b877f 100644 --- a/tests/architecture/test_doc_paths.py +++ b/tests/architecture/test_doc_paths.py @@ -69,6 +69,13 @@ REPO_ROOT = Path(__file__).resolve().parents[2] #: ``docs/reference/api-stable.md`` a été migré vers les chemins #: canoniques ``picarones.evaluation.{benchmark_result, corpus, #: pipeline}``. +#: - 88 (sprint « Lot D — measurements/X (34 shims) → evaluation/metrics », +#: 2026-05-07) : suppression des 34 shims plats de ``measurements/``. +#: Cinq nouveaux chemins cassés héritage : 4 dans ``docs/audits/*.md`` +#: (intouchable) + 1 dans ``docs/roadmap/evolution-2026.md`` +#: (plan stratégique historique). Les docs actifs ``CLAUDE.md``, +#: ``README.md`` et ``SPECS.md`` ont été corrigés en place vers +#: ``picarones/formats/text/normalization.py``. #: #: Les chemins cassés restants sont **TOUS** dans : #: - ``CHANGELOG.md`` : journal historique versionné, intouchable. @@ -77,7 +84,7 @@ REPO_ROOT = Path(__file__).resolve().parents[2] #: - ``docs/migration/executor-equivalence.md`` : audit historique #: d'équivalence executor (cite des chemins legacy à des fins #: de comparaison). -BROKEN_PATHS_BASELINE = 83 +BROKEN_PATHS_BASELINE = 88 #: Patrons de fichiers de documentation à scanner. DOC_GLOBS: tuple[str, ...] = ( diff --git a/tests/architecture/test_file_budgets.py b/tests/architecture/test_file_budgets.py index 349963f3cdce744f9db16aa0bc15e13fd7706a9a..63568294bab85213697f87be55c69bd4654036ac 100644 --- a/tests/architecture/test_file_budgets.py +++ b/tests/architecture/test_file_budgets.py @@ -74,10 +74,9 @@ FILE_BUDGETS: dict[str, int] = { "picarones/evaluation/pipeline.py": 700, # actuel 622 "picarones/extras/importers/iiif.py": 675, # actuel 567 "picarones/extras/importers/gallica.py": 675, # actuel 563 - "picarones/measurements/levers.py": 675, # actuel 561 (re-export S10) - # Sprint A14-S10 — déplacés depuis measurements/, l'ancien - # emplacement est désormais un re-export. Le contenu canonique - # vit dans evaluation/metrics/. + # Sprint A14-S10 + Lot D — déplacés depuis measurements/. + # L'ancien emplacement (shim) a été supprimé au Lot D ; seul le + # canonique reste dans evaluation/metrics/. "picarones/evaluation/metrics/levers.py": 675, # actuel 561 "picarones/evaluation/metrics/inter_engine.py": 575, # actuel 484 "picarones/extras/importers/escriptorium.py": 650, # actuel 553 @@ -120,10 +119,9 @@ FILE_BUDGETS: dict[str, int] = { # (Document/Corpus/GTLevel + 5 payloads + load_corpus_from_directory). "picarones/evaluation/corpus.py": 600, # actuel 533 "picarones/fixtures.py": 600, # actuel 510 - "picarones/measurements/inter_engine.py": 575, # actuel 484 - # Phase 5.C.batch7 : ``measurements/roman_numerals.py`` est - # désormais un shim ; canonique dans - # ``evaluation/metrics/roman_numerals.py``. + # Phase 5.C.batch7 + Lot D : le shim + # ``measurements/roman_numerals.py`` a été supprimé. Seul le + # canonique ``evaluation/metrics/roman_numerals.py`` reste. "picarones/evaluation/metrics/roman_numerals.py": 575, # actuel 484 "picarones/extras/importers/htr_united.py": 575, # actuel 473 (re-export S11) # Sprint A14-S11 — d\xc3\xa9plac\xc3\xa9s depuis extras/importers/, l'ancien @@ -141,10 +139,8 @@ FILE_BUDGETS: dict[str, int] = { # désormais un shim ; canonique dans # ``evaluation/metrics/numerical_sequences.py``. "picarones/evaluation/metrics/numerical_sequences.py": 500, # actuel 428 - "picarones/measurements/normalization.py": 500, # actuel 420 (re-export S9) - # Sprint A14-S9 — déplacé depuis measurements/normalization.py. - # L'ancien emplacement est désormais un re-export ; le contenu - # canonique vit ici. + # Sprint A14-S9 + Lot D — déplacé depuis measurements/normalization.py. + # Le shim a été supprimé au Lot D ; seul le canonique reste. "picarones/formats/text/normalization.py": 500, # actuel 420 # Phase 5.E : ``report/comparison.py`` est désormais un shim ; # canonique dans ``reports_v2/html/comparison.py``. diff --git a/tests/architecture/test_module_coverage.py b/tests/architecture/test_module_coverage.py index e7081bdc9676b4b22ae7ab46b824078cd39b6b55..474d186d792848497dd0ffa00822b7f5b575429a 100644 --- a/tests/architecture/test_module_coverage.py +++ b/tests/architecture/test_module_coverage.py @@ -61,46 +61,17 @@ MEASUREMENTS_DIR = PICARONES_DIR / "measurements" #: de fin de ligne ``noqa F401`` dans #: ``picarones/measurements/__init__.py``). TEST_ONLY_BASELINE: frozenset[str] = frozenset({ - # Phase 5.C : modules ``measurements/X.py`` qui sont des shims - # vers ``evaluation/metrics/X``. Leur unique consommateur - # production (le renderer ``report/X_render.py``) a été migré - # vers ``reports_v2/html/renderers/X.py`` qui importe le - # canonique directement (la règle layer-dependencies interdit - # d'importer un shim depuis ``reports_v2/``). Tant que des - # tests ou un caller externe utilisent le chemin legacy, le - # shim reste en place ; les entrées ici sont retirées au plus - # tard à la version 2.0 quand les shims disparaîtront. - "specialization", - "lexical_modernization", - "robustness_projection", - # Phase 5.C.batch7 : 4 modules supplémentaires migrés vers - # ``evaluation/`` (``numerical_sequences``, - # ``pipeline_benchmark``, ``pipeline_comparison``) ou - # ``evaluation/metrics/`` (``numerical_sequences``). - # ``numerical_sequences_hooks`` n'est plus consommé en prod - # car son seul consommateur (le renderer) consomme désormais - # le canonique. - "numerical_sequences", + # Lot D — la majorité des entrées historiques (shims + # ``measurements/X.py`` vers ``evaluation/metrics/X``) ont été + # supprimées au Lot D, donc retirées de cette baseline. Ne + # restent que les modules qui n'ont pas de canonique migré et + # dont le seul consommateur production est désormais hors + # ``picarones/`` (renderer canonique qui consomme le canonique + # directement, mais module legacy gardé pour les tests). "numerical_sequences_hooks", "pipeline_benchmark", "pipeline_comparison", - # Phase 5.D : 6 modules supplémentaires consommés uniquement - # par les 5 vues thématiques migrées vers - # ``reports_v2/html/views/``, qui importent désormais le - # canonique directement. - "taxonomy_comparison", - "incremental_comparison", - "levers", - "image_predictive", - "worst_lines", - "throughput", - # Phase 5.E : 3 modules supplémentaires consommés uniquement - # par les renderers/views/data migrés vers - # ``reports_v2/html/`` qui importent désormais le canonique - # directement. "statistics", - "pricing", - "difficulty", }) diff --git a/tests/architecture/test_no_flat_files_in_measurements.py b/tests/architecture/test_no_flat_files_in_measurements.py index 62278115849ece2009f3a00ce9c6c280e9d4a17a..82c3c4491095487dfefd383d8e6059b18c104ef4 100644 --- a/tests/architecture/test_no_flat_files_in_measurements.py +++ b/tests/architecture/test_no_flat_files_in_measurements.py @@ -44,62 +44,28 @@ WHITELIST_FLAT_FILES_S3: frozenset[str] = frozenset({ "__init__.py", "abbreviations.py", "alto_metrics.py", - "baseline_comparison.py", "builtin_hooks.py", "builtin_metrics.py", - "calibration.py", - "char_scores.py", - "confusion.py", - "cost_projection.py", - "difficulty.py", "early_modern_typography.py", "equivalence_profile.py", - "error_absorption.py", - "hallucination.py", "history.py", - "image_predictive.py", - "image_quality.py", - "incremental_comparison.py", - "inter_engine.py", - "layout.py", - "levers.py", - "lexical_modernization.py", - "line_metrics.py", - "longitudinal.py", - "marginal_cost.py", "metrics.py", "modern_archives.py", - "module_policy.py", "mufi.py", "ner.py", - "ner_backends.py", - "normalization.py", - "numerical_sequences.py", "numerical_sequences_hooks.py", "philological_hooks.py", "pipeline_benchmark.py", "pipeline_comparison.py", "pipeline_spec_loader.py", - "pricing.py", - "rare_tokens.py", "readability.py", "readability_hooks.py", "reading_order.py", "reliability.py", "robustness.py", - "robustness_projection.py", - "roman_numerals.py", "searchability.py", "searchability_hooks.py", - "specialization.py", - "structure.py", - "taxonomy.py", - "taxonomy_comparison.py", - "taxonomy_cooccurrence.py", - "taxonomy_intra_doc.py", - "throughput.py", "unicode_blocks.py", - "worst_lines.py", }) diff --git a/tests/engines/test_sprint4_normalization_iiif.py b/tests/engines/test_sprint4_normalization_iiif.py index 7bf2b7d658a1b9a89f104712d84b35c9a3af78b8..d987dfeced70f9fefd1c8f08332dac80eb9c0c73 100644 --- a/tests/engines/test_sprint4_normalization_iiif.py +++ b/tests/engines/test_sprint4_normalization_iiif.py @@ -4,7 +4,7 @@ from __future__ import annotations import pytest -from picarones.measurements.normalization import ( +from picarones.evaluation.metrics.normalization import ( NormalizationProfile, DEFAULT_DIPLOMATIC_PROFILE, _apply_diplomatic_table, @@ -205,7 +205,7 @@ class TestDiplomaticCER: assert "diplomatic_profile_name" in d def test_cer_diplomatic_with_custom_profile(self): - from picarones.measurements.normalization import NormalizationProfile + from picarones.evaluation.metrics.normalization import NormalizationProfile profile = NormalizationProfile( name="test_profile", diplomatic_table={"ſ": "s"} diff --git a/tests/formats/text/test_sprint_a14_s9_normalization_migration.py b/tests/formats/text/test_sprint_a14_s9_normalization_migration.py index f3e5fd76190324a7b4246dc35b652127cb076406..d84a40215017e9f0398d6bb59d0151ff84845e45 100644 --- a/tests/formats/text/test_sprint_a14_s9_normalization_migration.py +++ b/tests/formats/text/test_sprint_a14_s9_normalization_migration.py @@ -29,7 +29,7 @@ def test_new_path_exposes_all_eleven_profiles() -> None: def test_old_reexport_works() -> None: """Compat ascendante : ~50 consommateurs importent depuis l'ancien chemin.""" - from picarones.measurements.normalization import ( + from picarones.evaluation.metrics.normalization import ( DEFAULT_DIPLOMATIC_PROFILE, NORMALIZATION_PROFILES, NormalizationProfile, @@ -44,7 +44,7 @@ def test_old_reexport_works() -> None: def test_private_symbols_reexported() -> None: """Les symboles préfixés ``_`` utilisés en aval doivent rester importables depuis l'ancien chemin.""" - from picarones.measurements.normalization import ( + from picarones.evaluation.metrics.normalization import ( _apply_diplomatic_table, _parse_exclude_chars, ) @@ -59,7 +59,7 @@ def test_old_and_new_paths_share_same_objects() -> None: NormalizationProfile as NewProfile, get_builtin_profile as new_get, ) - from picarones.measurements.normalization import ( + from picarones.evaluation.metrics.normalization import ( NORMALIZATION_PROFILES as old_profiles, NormalizationProfile as OldProfile, get_builtin_profile as old_get, diff --git a/tests/integration/test_sprint11_i18n_english.py b/tests/integration/test_sprint11_i18n_english.py index 0daacdb197bb9a81c0b9a98cae8e87b43922c2ab..6508dba82344cf1a68d6d66e28cd951dc2e9e86c 100644 --- a/tests/integration/test_sprint11_i18n_english.py +++ b/tests/integration/test_sprint11_i18n_english.py @@ -26,7 +26,7 @@ class TestEarlyModernEnglish: @pytest.fixture def profile(self): - from picarones.measurements.normalization import get_builtin_profile + from picarones.evaluation.metrics.normalization import get_builtin_profile return get_builtin_profile("early_modern_english") def test_profile_exists(self, profile): @@ -89,7 +89,7 @@ class TestMedievalEnglish: @pytest.fixture def profile(self): - from picarones.measurements.normalization import get_builtin_profile + from picarones.evaluation.metrics.normalization import get_builtin_profile return get_builtin_profile("medieval_english") def test_profile_exists(self, profile): @@ -129,7 +129,7 @@ class TestSecretaryHand: @pytest.fixture def profile(self): - from picarones.measurements.normalization import get_builtin_profile + from picarones.evaluation.metrics.normalization import get_builtin_profile return get_builtin_profile("secretary_hand") def test_profile_exists(self, profile): @@ -160,18 +160,18 @@ class TestBuiltinProfilesListing: """Vérifie que les 3 nouveaux profils sont bien accessibles.""" def test_all_english_profiles_accessible(self): - from picarones.measurements.normalization import get_builtin_profile + from picarones.evaluation.metrics.normalization import get_builtin_profile for name in ("early_modern_english", "medieval_english", "secretary_hand"): p = get_builtin_profile(name) assert p.name == name def test_unknown_profile_raises_key_error(self): - from picarones.measurements.normalization import get_builtin_profile + from picarones.evaluation.metrics.normalization import get_builtin_profile with pytest.raises(KeyError): get_builtin_profile("unknown_lang_profile_xyz") def test_existing_profiles_still_work(self): - from picarones.measurements.normalization import get_builtin_profile + from picarones.evaluation.metrics.normalization import get_builtin_profile for name in ("medieval_french", "early_modern_french", "medieval_latin", "nfc", "caseless", "minimal"): p = get_builtin_profile(name) assert p.name == name diff --git a/tests/integration/test_sprint13_parallelisation_stats.py b/tests/integration/test_sprint13_parallelisation_stats.py index 86873192a2aa803d04ae305ab55068ab5a27c512..b4e26d8ef1d5aea8c2462ff0eb3a4341f6fc013e 100644 --- a/tests/integration/test_sprint13_parallelisation_stats.py +++ b/tests/integration/test_sprint13_parallelisation_stats.py @@ -375,7 +375,7 @@ class TestRunnerSilentExceptions: "picarones.measurements.runner._compute_document_result", wraps=__import__("picarones.measurements.runner", fromlist=["_compute_document_result"])._compute_document_result, ): - with patch("picarones.measurements.confusion.build_confusion_matrix", side_effect=RuntimeError("crash test")): + with patch("picarones.evaluation.metrics.confusion.build_confusion_matrix", side_effect=RuntimeError("crash test")): with caplog.at_level(logging.WARNING): result = run_benchmark(corpus, [MockEngine()], show_progress=False) diff --git a/tests/integration/test_sprint94_error_absorption.py b/tests/integration/test_sprint94_error_absorption.py index 8df001dbec9be88cfe0f4744162745826a379703..3829b5c0873c2c0304616fd008e16580baaab0dc 100644 --- a/tests/integration/test_sprint94_error_absorption.py +++ b/tests/integration/test_sprint94_error_absorption.py @@ -25,7 +25,7 @@ from pathlib import Path import pytest -from picarones.measurements.error_absorption import ( +from picarones.evaluation.metrics.error_absorption import ( aggregate_error_absorption, compute_error_absorption, ) diff --git a/tests/measurements/test_char_scores.py b/tests/measurements/test_char_scores.py index 4d8d09f1e819e7488c3deec7b34d65ac2db6c5d6..68ddcec5743ee83a8c3a5ec2e7b3c50b098d65be 100644 --- a/tests/measurements/test_char_scores.py +++ b/tests/measurements/test_char_scores.py @@ -20,7 +20,7 @@ from __future__ import annotations import pytest -from picarones.measurements.char_scores import ( +from picarones.evaluation.metrics.char_scores import ( DiacriticScore, LigatureScore, aggregate_diacritic_scores, diff --git a/tests/measurements/test_pricing_degenerate_cases.py b/tests/measurements/test_pricing_degenerate_cases.py index 88d5fd439b42e2baf4cde1c449dc4220063bb8b4..632d471e954292b911a7c32a09100cf6c455267c 100644 --- a/tests/measurements/test_pricing_degenerate_cases.py +++ b/tests/measurements/test_pricing_degenerate_cases.py @@ -19,7 +19,7 @@ from __future__ import annotations import pytest -from picarones.measurements.pricing import ( +from picarones.evaluation.metrics.pricing import ( EngineCost, PricingDefaults, build_costs_for_benchmark, diff --git a/tests/measurements/test_sprint10_error_distribution.py b/tests/measurements/test_sprint10_error_distribution.py index 2217f64a62c782b0b39efdbe9e707beca6c378e4..caecbdd2c56541a4b590abdbb2d46b2ba3a0f774 100644 --- a/tests/measurements/test_sprint10_error_distribution.py +++ b/tests/measurements/test_sprint10_error_distribution.py @@ -44,28 +44,28 @@ class TestLineMetrics: """Tests pour picarones.measurements.line_metrics.compute_line_metrics.""" def test_import(self): - from picarones.measurements.line_metrics import compute_line_metrics, LineMetrics + from picarones.evaluation.metrics.line_metrics import compute_line_metrics, LineMetrics assert callable(compute_line_metrics) assert LineMetrics is not None def test_perfect_match_cer_zero(self): - from picarones.measurements.line_metrics import compute_line_metrics + from picarones.evaluation.metrics.line_metrics import compute_line_metrics result = compute_line_metrics(GT_MULTILINE, HYP_MULTILINE_PERFECT) assert result.mean_cer == pytest.approx(0.0, abs=1e-9) assert all(v == pytest.approx(0.0, abs=1e-9) for v in result.cer_per_line) def test_line_count(self): - from picarones.measurements.line_metrics import compute_line_metrics + from picarones.evaluation.metrics.line_metrics import compute_line_metrics result = compute_line_metrics(GT_MULTILINE, HYP_MULTILINE_ERRORS) assert result.line_count == 3 def test_cer_per_line_length(self): - from picarones.measurements.line_metrics import compute_line_metrics + from picarones.evaluation.metrics.line_metrics import compute_line_metrics result = compute_line_metrics(GT_MULTILINE, HYP_MULTILINE_ERRORS) assert len(result.cer_per_line) == 3 def test_percentiles_keys(self): - from picarones.measurements.line_metrics import compute_line_metrics + from picarones.evaluation.metrics.line_metrics import compute_line_metrics result = compute_line_metrics(GT_MULTILINE, HYP_MULTILINE_ERRORS) for key in ("p50", "p75", "p90", "p95", "p99"): assert key in result.percentiles @@ -73,23 +73,23 @@ class TestLineMetrics: def test_percentile_ordering(self): """p50 ≤ p75 ≤ p90 ≤ p95 ≤ p99.""" - from picarones.measurements.line_metrics import compute_line_metrics + from picarones.evaluation.metrics.line_metrics import compute_line_metrics result = compute_line_metrics(GT_MULTILINE, HYP_MULTILINE_ERRORS) p = result.percentiles assert p["p50"] <= p["p75"] <= p["p90"] <= p["p95"] <= p["p99"] def test_gini_zero_for_perfect(self): - from picarones.measurements.line_metrics import compute_line_metrics + from picarones.evaluation.metrics.line_metrics import compute_line_metrics result = compute_line_metrics(GT_MULTILINE, HYP_MULTILINE_PERFECT) assert result.gini == pytest.approx(0.0, abs=1e-9) def test_gini_range(self): - from picarones.measurements.line_metrics import compute_line_metrics + from picarones.evaluation.metrics.line_metrics import compute_line_metrics result = compute_line_metrics(GT_MULTILINE, HYP_MULTILINE_ERRORS) assert 0.0 <= result.gini <= 1.0 def test_catastrophic_rate_keys(self): - from picarones.measurements.line_metrics import compute_line_metrics + from picarones.evaluation.metrics.line_metrics import compute_line_metrics result = compute_line_metrics(GT_MULTILINE, HYP_MULTILINE_ERRORS, thresholds=[0.30, 0.50, 1.00]) for t in (0.30, 0.50, 1.00): @@ -97,12 +97,12 @@ class TestLineMetrics: assert 0.0 <= result.catastrophic_rate[t] <= 1.0 def test_heatmap_length(self): - from picarones.measurements.line_metrics import compute_line_metrics + from picarones.evaluation.metrics.line_metrics import compute_line_metrics result = compute_line_metrics(GT_MULTILINE, HYP_MULTILINE_ERRORS, heatmap_bins=5) assert len(result.heatmap) == 5 def test_as_dict_and_from_dict_roundtrip(self): - from picarones.measurements.line_metrics import compute_line_metrics, LineMetrics + from picarones.evaluation.metrics.line_metrics import compute_line_metrics, LineMetrics result = compute_line_metrics(GT_MULTILINE, HYP_MULTILINE_ERRORS) d = result.as_dict() restored = LineMetrics.from_dict(d) @@ -111,7 +111,7 @@ class TestLineMetrics: assert len(restored.cer_per_line) == len(result.cer_per_line) def test_aggregate_line_metrics(self): - from picarones.measurements.line_metrics import compute_line_metrics, aggregate_line_metrics + from picarones.evaluation.metrics.line_metrics import compute_line_metrics, aggregate_line_metrics r1 = compute_line_metrics(GT_MULTILINE, HYP_MULTILINE_PERFECT) r2 = compute_line_metrics(GT_MULTILINE, HYP_MULTILINE_ERRORS) agg = aggregate_line_metrics([r1, r2]) @@ -131,61 +131,61 @@ class TestHallucinationMetrics: """Tests pour picarones.measurements.hallucination.compute_hallucination_metrics.""" def test_import(self): - from picarones.measurements.hallucination import compute_hallucination_metrics, HallucinationMetrics + from picarones.evaluation.metrics.hallucination import compute_hallucination_metrics, HallucinationMetrics assert callable(compute_hallucination_metrics) assert HallucinationMetrics is not None def test_perfect_match_anchor_one(self): - from picarones.measurements.hallucination import compute_hallucination_metrics + from picarones.evaluation.metrics.hallucination import compute_hallucination_metrics result = compute_hallucination_metrics(GT_SIMPLE, HYP_PERFECT) # Ancrage parfait → score proche de 1.0 assert result.anchor_score == pytest.approx(1.0, abs=0.05) assert result.is_hallucinating is False def test_length_ratio_perfect(self): - from picarones.measurements.hallucination import compute_hallucination_metrics + from picarones.evaluation.metrics.hallucination import compute_hallucination_metrics result = compute_hallucination_metrics(GT_SIMPLE, HYP_PERFECT) assert result.length_ratio == pytest.approx(1.0, abs=0.05) def test_hallucination_detected(self): - from picarones.measurements.hallucination import compute_hallucination_metrics + from picarones.evaluation.metrics.hallucination import compute_hallucination_metrics result = compute_hallucination_metrics(GT_MEDIEVAL, HYP_HALLUCINATED) # L'hypothèse est beaucoup plus longue assert result.length_ratio > 1.0 assert result.is_hallucinating is True def test_hallucinated_blocks_detected(self): - from picarones.measurements.hallucination import compute_hallucination_metrics + from picarones.evaluation.metrics.hallucination import compute_hallucination_metrics result = compute_hallucination_metrics(GT_MEDIEVAL, HYP_HALLUCINATED, anchor_threshold=0.5, min_block_length=3) # Des blocs hallucinés doivent être détectés assert len(result.hallucinated_blocks) > 0 def test_net_insertion_rate_range(self): - from picarones.measurements.hallucination import compute_hallucination_metrics + from picarones.evaluation.metrics.hallucination import compute_hallucination_metrics result = compute_hallucination_metrics(GT_MEDIEVAL, HYP_HALLUCINATED) assert 0.0 <= result.net_insertion_rate <= 1.0 def test_word_counts(self): - from picarones.measurements.hallucination import compute_hallucination_metrics + from picarones.evaluation.metrics.hallucination import compute_hallucination_metrics result = compute_hallucination_metrics(GT_SIMPLE, HYP_PERFECT) assert result.gt_word_count > 0 assert result.hyp_word_count > 0 def test_empty_reference(self): - from picarones.measurements.hallucination import compute_hallucination_metrics + from picarones.evaluation.metrics.hallucination import compute_hallucination_metrics result = compute_hallucination_metrics("", "some text here added by model") # Référence vide : insertion nette maximale assert result.net_insertion_rate == pytest.approx(1.0, abs=0.05) def test_empty_hypothesis(self): - from picarones.measurements.hallucination import compute_hallucination_metrics + from picarones.evaluation.metrics.hallucination import compute_hallucination_metrics result = compute_hallucination_metrics(GT_SIMPLE, "") assert result.hyp_word_count == 0 assert result.net_insertion_rate == pytest.approx(0.0) def test_as_dict_and_from_dict_roundtrip(self): - from picarones.measurements.hallucination import compute_hallucination_metrics, HallucinationMetrics + from picarones.evaluation.metrics.hallucination import compute_hallucination_metrics, HallucinationMetrics result = compute_hallucination_metrics(GT_MEDIEVAL, HYP_HALLUCINATED) d = result.as_dict() restored = HallucinationMetrics.from_dict(d) @@ -194,7 +194,7 @@ class TestHallucinationMetrics: assert len(restored.hallucinated_blocks) == len(result.hallucinated_blocks) def test_aggregate_hallucination_metrics(self): - from picarones.measurements.hallucination import compute_hallucination_metrics, aggregate_hallucination_metrics + from picarones.evaluation.metrics.hallucination import compute_hallucination_metrics, aggregate_hallucination_metrics r1 = compute_hallucination_metrics(GT_SIMPLE, HYP_PERFECT) r2 = compute_hallucination_metrics(GT_MEDIEVAL, HYP_HALLUCINATED) agg = aggregate_hallucination_metrics([r1, r2]) @@ -207,7 +207,7 @@ class TestHallucinationMetrics: def test_anchor_threshold_respected(self): """Un ancrage très bas déclenche le badge hallucination.""" - from picarones.measurements.hallucination import compute_hallucination_metrics + from picarones.evaluation.metrics.hallucination import compute_hallucination_metrics result = compute_hallucination_metrics( "abc def ghi", "xyz uvw rst opq lmn", anchor_threshold=0.5 diff --git a/tests/measurements/test_sprint12_nouvelles_fonctionnalites.py b/tests/measurements/test_sprint12_nouvelles_fonctionnalites.py index 170eb08771818e16c34d626d216e8b984842b1e1..fe99928c32bda14f5c036e2910082c6b3e448c1f 100644 --- a/tests/measurements/test_sprint12_nouvelles_fonctionnalites.py +++ b/tests/measurements/test_sprint12_nouvelles_fonctionnalites.py @@ -71,7 +71,7 @@ class TestMacOSHiddenFilesFiltering: class TestExcludeCharsNormalization: def test_parse_exclude_chars_from_comma_string(self): - from picarones.measurements.normalization import _parse_exclude_chars + from picarones.evaluation.metrics.normalization import _parse_exclude_chars result = _parse_exclude_chars("', -, –") assert "'" in result @@ -79,7 +79,7 @@ class TestExcludeCharsNormalization: assert "–" in result def test_parse_exclude_chars_from_plain_string(self): - from picarones.measurements.normalization import _parse_exclude_chars + from picarones.evaluation.metrics.normalization import _parse_exclude_chars result = _parse_exclude_chars(".,;:!?") assert "." in result @@ -87,13 +87,13 @@ class TestExcludeCharsNormalization: assert "?" in result def test_parse_exclude_chars_empty(self): - from picarones.measurements.normalization import _parse_exclude_chars + from picarones.evaluation.metrics.normalization import _parse_exclude_chars assert _parse_exclude_chars("") == frozenset() assert _parse_exclude_chars(None) == frozenset() def test_normalize_strips_excluded_chars(self): - from picarones.measurements.normalization import NormalizationProfile + from picarones.evaluation.metrics.normalization import NormalizationProfile profile = NormalizationProfile( name="test", @@ -102,7 +102,7 @@ class TestExcludeCharsNormalization: assert profile.normalize("Bonjour, monde.") == "Bonjour monde" def test_sans_ponctuation_profile_exists(self): - from picarones.measurements.normalization import NORMALIZATION_PROFILES + from picarones.evaluation.metrics.normalization import NORMALIZATION_PROFILES assert "sans_ponctuation" in NORMALIZATION_PROFILES p = NORMALIZATION_PROFILES["sans_ponctuation"] @@ -111,7 +111,7 @@ class TestExcludeCharsNormalization: assert "?" in p.exclude_chars def test_sans_apostrophes_profile_exists(self): - from picarones.measurements.normalization import NORMALIZATION_PROFILES + from picarones.evaluation.metrics.normalization import NORMALIZATION_PROFILES assert "sans_apostrophes" in NORMALIZATION_PROFILES p = NORMALIZATION_PROFILES["sans_apostrophes"] diff --git a/tests/measurements/test_sprint20_pareto_pricing.py b/tests/measurements/test_sprint20_pareto_pricing.py index 53ce8a4c98ff6b94dd3c041a5cbc4a9bf386f9de..69da41e2e9dda688003f530c23961ddbb99b9b61 100644 --- a/tests/measurements/test_sprint20_pareto_pricing.py +++ b/tests/measurements/test_sprint20_pareto_pricing.py @@ -21,7 +21,7 @@ from picarones.measurements.narrative.detectors import ( detect_pareto_alternative, ) from picarones.domain.facts import FactType -from picarones.measurements.pricing import ( +from picarones.evaluation.metrics.pricing import ( build_costs_for_benchmark, estimate_cost, load_pricing_database, @@ -306,7 +306,7 @@ class TestReportIntegration: def test_pricing_yaml_is_packaged(self): """Garde-fou : le YAML doit être accessible depuis le package.""" - from picarones.measurements.pricing import _DEFAULT_PRICING_PATH + from picarones.evaluation.metrics.pricing import _DEFAULT_PRICING_PATH assert Path(_DEFAULT_PRICING_PATH).exists() def test_english_locale_renders_pareto_labels(self, benchmark_result, tmp_path): diff --git a/tests/measurements/test_sprint35_inter_engine.py b/tests/measurements/test_sprint35_inter_engine.py index 1d10aec2bb0d9caf4eac5fb7d6ba6b04216c63df..6d14fb2dcd3814c160f86cc93abf1e1094d7936a 100644 --- a/tests/measurements/test_sprint35_inter_engine.py +++ b/tests/measurements/test_sprint35_inter_engine.py @@ -23,7 +23,7 @@ import math import pytest -from picarones.measurements.inter_engine import ( +from picarones.evaluation.metrics.inter_engine import ( complementarity_gap, jensen_shannon_divergence, kl_divergence, @@ -187,7 +187,7 @@ class TestOracleTokenRecall: } assert oracle_token_recall(ref, hyps) == pytest.approx(1.0) # Et chacun seul ne fait que la moitié - from picarones.measurements.inter_engine import complementarity_gap + from picarones.evaluation.metrics.inter_engine import complementarity_gap gap = complementarity_gap(ref, hyps) assert gap["best_single_recall"] == pytest.approx(0.5) assert gap["oracle_recall"] == pytest.approx(1.0) diff --git a/tests/measurements/test_sprint36_ensemble_narrative.py b/tests/measurements/test_sprint36_ensemble_narrative.py index ab64f564f55492e02978f4a8d2dc9de79dbe9d5b..8f34a7311297d68e8b1a73cbb346f0f92a3f1da7 100644 --- a/tests/measurements/test_sprint36_ensemble_narrative.py +++ b/tests/measurements/test_sprint36_ensemble_narrative.py @@ -22,7 +22,7 @@ import re import pytest -from picarones.measurements.inter_engine import compute_inter_engine_analysis +from picarones.evaluation.metrics.inter_engine import compute_inter_engine_analysis from picarones.measurements.narrative.detectors import detect_ensemble_opportunity from picarones.domain.facts import FactImportance, FactType from picarones.measurements.narrative.renderer import extract_numbers, render_fact diff --git a/tests/measurements/test_sprint39_calibration.py b/tests/measurements/test_sprint39_calibration.py index 6eb3fcde92e9d50caaf81e4d061ba4cc8a9959a0..11411ee612f20b80503663c37bc396c991fde0eb 100644 --- a/tests/measurements/test_sprint39_calibration.py +++ b/tests/measurements/test_sprint39_calibration.py @@ -34,7 +34,7 @@ from __future__ import annotations import pytest -from picarones.measurements.calibration import ( +from picarones.evaluation.metrics.calibration import ( CalibrationBin, compute_calibration_metrics, expected_calibration_error, diff --git a/tests/measurements/test_sprint40_ner_runner.py b/tests/measurements/test_sprint40_ner_runner.py index da70916ab68ddc85af79ad1436ace3fd66bf6bfa..fca86da34651546c59d181f88a4ddf3a9058c112 100644 --- a/tests/measurements/test_sprint40_ner_runner.py +++ b/tests/measurements/test_sprint40_ner_runner.py @@ -27,7 +27,7 @@ from pathlib import Path import pytest from picarones.evaluation.corpus import Corpus, Document, EntitiesGT, GTLevel, TextGT -from picarones.measurements.ner_backends import ( +from picarones.evaluation.metrics.ner_backends import ( SPACY_PROFILES, SpacyEntityExtractor, get_extractor, @@ -49,7 +49,7 @@ class TestSpacyExtractor: """Sans spaCy installé, l'extracteur retourne [] avec un warning explicite et ne lève pas.""" ext = SpacyEntityExtractor("fr_core_news_sm") - with caplog.at_level("WARNING", logger="picarones.measurements.ner_backends"): + with caplog.at_level("WARNING", logger="picarones.evaluation.metrics.ner_backends"): result = ext("Marie de Bourgogne en 1477.") # Sans spaCy, on a toujours [] et un warning if not is_spacy_available(): diff --git a/tests/measurements/test_sprint54_layout.py b/tests/measurements/test_sprint54_layout.py index f7afb4f1da430f9148dedbcc6ad07716fb194c6c..5e5f5486a047e72d2c32d5d75d82d1087d6d4533 100644 --- a/tests/measurements/test_sprint54_layout.py +++ b/tests/measurements/test_sprint54_layout.py @@ -22,7 +22,7 @@ from __future__ import annotations import pytest -from picarones.measurements.layout import ( +from picarones.evaluation.metrics.layout import ( Region, _iou_bbox, compute_layout_metrics, diff --git a/tests/measurements/test_sprint60_roman_numerals.py b/tests/measurements/test_sprint60_roman_numerals.py index 41332a293dc0b6d55761986574a403e6db0f295e..708840431e66380c5fac21c3e906a42d04d56944 100644 --- a/tests/measurements/test_sprint60_roman_numerals.py +++ b/tests/measurements/test_sprint60_roman_numerals.py @@ -385,7 +385,7 @@ class TestShortcuts: class TestRegistryIntegration: def test_metrics_registered(self) -> None: - import picarones.measurements.roman_numerals # noqa: F401 + import picarones.evaluation.metrics.roman_numerals # noqa: F401 selected = select_metrics( (ArtifactType.TEXT, ArtifactType.TEXT), diff --git a/tests/measurements/test_sprint71_rare_tokens.py b/tests/measurements/test_sprint71_rare_tokens.py index 44b4a89f0c60ba523dc19c591cf14737ee2b80b9..eae165e7ae51984fb5fe7536aebac2c8aea5f1ad 100644 --- a/tests/measurements/test_sprint71_rare_tokens.py +++ b/tests/measurements/test_sprint71_rare_tokens.py @@ -24,7 +24,7 @@ from __future__ import annotations import pytest -from picarones.measurements.rare_tokens import ( +from picarones.evaluation.metrics.rare_tokens import ( compute_rare_token_recall, extract_rare_tokens, frequency_distribution, diff --git a/tests/measurements/test_sprint73_baseline_comparison.py b/tests/measurements/test_sprint73_baseline_comparison.py index 7d7a8fd36a53748c997a300659d42dbafd1ccac2..05f3e346a8bc2f1df8b4344b9a5b5b1bd5cb8ddc 100644 --- a/tests/measurements/test_sprint73_baseline_comparison.py +++ b/tests/measurements/test_sprint73_baseline_comparison.py @@ -31,7 +31,7 @@ from typing import Any, Optional import pytest -from picarones.measurements.baseline_comparison import ( +from picarones.evaluation.metrics.baseline_comparison import ( compute_corpus_difficulty_percentile, compute_engine_baseline, ) diff --git a/tests/measurements/test_sprint79_cost_projection.py b/tests/measurements/test_sprint79_cost_projection.py index e9a47c16ec3967ef998bf4670aafa00100e45ca4..599fcfdb083fc72101a4007b4a078695291c263f 100644 --- a/tests/measurements/test_sprint79_cost_projection.py +++ b/tests/measurements/test_sprint79_cost_projection.py @@ -23,7 +23,7 @@ from __future__ import annotations import pytest -from picarones.measurements.cost_projection import ( +from picarones.evaluation.metrics.cost_projection import ( ProjectedCost, cost_gap_table, project_all_engines, @@ -31,7 +31,7 @@ from picarones.measurements.cost_projection import ( project_cost_total, project_engine, ) -from picarones.measurements.pricing import EngineCost +from picarones.evaluation.metrics.pricing import EngineCost def _ec(name: str, cost_1k: float | None, co2_1k: float | None = None, diff --git a/tests/measurements/test_sprint81_robustness_projection.py b/tests/measurements/test_sprint81_robustness_projection.py index c6da5e8919e6f921fd047b044b6b402836f8ef6c..7e9217eea56586ec31ed3c22df386a3984057023 100644 --- a/tests/measurements/test_sprint81_robustness_projection.py +++ b/tests/measurements/test_sprint81_robustness_projection.py @@ -24,7 +24,7 @@ from __future__ import annotations import pytest -from picarones.measurements.robustness_projection import ( +from picarones.evaluation.metrics.robustness_projection import ( _extract_quality_value, _interpolate_cer, aggregate_projection_per_engine, diff --git a/tests/measurements/test_sprint93_image_predictive.py b/tests/measurements/test_sprint93_image_predictive.py index a5b26407f422532c773040054c83b15288c984d2..28328b484e4f3a541eaf8544157ee855fe048446 100644 --- a/tests/measurements/test_sprint93_image_predictive.py +++ b/tests/measurements/test_sprint93_image_predictive.py @@ -29,7 +29,7 @@ from pathlib import Path import pytest -from picarones.measurements.image_predictive import ( +from picarones.evaluation.metrics.image_predictive import ( DEFAULT_COMPLEXITY_WEIGHTS, aggregate_corpus_predictive, compute_corpus_homogeneity, diff --git a/tests/measurements/test_sprint96_incremental_comparison.py b/tests/measurements/test_sprint96_incremental_comparison.py index d0731d12ca3d072834b65ff35e94af894a99d026..b5d05c3eb6ef6bf39a5fb62ce605d8015dfb84f1 100644 --- a/tests/measurements/test_sprint96_incremental_comparison.py +++ b/tests/measurements/test_sprint96_incremental_comparison.py @@ -27,7 +27,7 @@ from pathlib import Path import pytest -from picarones.measurements.incremental_comparison import ( +from picarones.evaluation.metrics.incremental_comparison import ( PipelineRun, compare_isolated_effect, ) diff --git a/tests/measurements/test_sprint97_module_policy.py b/tests/measurements/test_sprint97_module_policy.py index 177fed6e87b7bd66d33696015345c3c32e8c1739..0f99175580ac1e26f0428ce6a15368cc8c053983 100644 --- a/tests/measurements/test_sprint97_module_policy.py +++ b/tests/measurements/test_sprint97_module_policy.py @@ -28,7 +28,7 @@ from __future__ import annotations import json from pathlib import Path -from picarones.measurements.module_policy import ( +from picarones.evaluation.metrics.module_policy import ( AuditCheck, AuditResult, ModuleManifest, diff --git a/tests/measurements/test_sprint_a14_s1_normalization_propagation.py b/tests/measurements/test_sprint_a14_s1_normalization_propagation.py index ef423c3e8b616d8c001912b3806a58749c2f4832..ccf29f129850f4a9f854caed282bba43678406f5 100644 --- a/tests/measurements/test_sprint_a14_s1_normalization_propagation.py +++ b/tests/measurements/test_sprint_a14_s1_normalization_propagation.py @@ -19,7 +19,7 @@ from __future__ import annotations import inspect -from picarones.measurements.normalization import ( +from picarones.evaluation.metrics.normalization import ( NORMALIZATION_PROFILES, get_builtin_profile, ) diff --git a/tests/report/test_sprint27_reproducibility_snapshots.py b/tests/report/test_sprint27_reproducibility_snapshots.py index 9568c0c8895f2fd3a52e4b531161cf17024e9f17..47f0c759de92c0fe66db9f9c0a022fba68e287ec 100644 --- a/tests/report/test_sprint27_reproducibility_snapshots.py +++ b/tests/report/test_sprint27_reproducibility_snapshots.py @@ -101,7 +101,7 @@ class TestGlossarySnapshot: class TestNormalizationSnapshot: def test_builtin_profile_serializes(self): - from picarones.measurements.normalization import get_builtin_profile + from picarones.evaluation.metrics.normalization import get_builtin_profile from picarones.reports_v2.html.snapshot import normalization_snapshot p = get_builtin_profile("medieval_french") s = normalization_snapshot(p) @@ -117,7 +117,7 @@ class TestNormalizationSnapshot: assert s["available"] is False def test_exclude_chars_sorted(self): - from picarones.measurements.normalization import get_builtin_profile + from picarones.evaluation.metrics.normalization import get_builtin_profile from picarones.reports_v2.html.snapshot import normalization_snapshot p = get_builtin_profile("sans_ponctuation") s = normalization_snapshot(p) @@ -171,7 +171,7 @@ class TestSnapshotAll: assert s["schema_version"] == 1 def test_deterministic_for_same_inputs(self): - from picarones.measurements.normalization import get_builtin_profile + from picarones.evaluation.metrics.normalization import get_builtin_profile from picarones.reports_v2.html.snapshot import snapshot_all profile = get_builtin_profile("nfc") @@ -192,7 +192,7 @@ class TestSnapshotAll: def generated_report_html(tmp_path_factory) -> str: """Génère un rapport démo et retourne son contenu HTML.""" from picarones import fixtures - from picarones.measurements.normalization import get_builtin_profile + from picarones.evaluation.metrics.normalization import get_builtin_profile from picarones.reports_v2.html.generator import ReportGenerator b = fixtures.generate_sample_benchmark(n_docs=6) diff --git a/tests/report/test_sprint5_advanced_metrics.py b/tests/report/test_sprint5_advanced_metrics.py index 1cf92cbcfbb9c3edef072d68e8817628cd211ea5..8d6dcc26890fc4a79a202e5babe1288c9141434f 100644 --- a/tests/report/test_sprint5_advanced_metrics.py +++ b/tests/report/test_sprint5_advanced_metrics.py @@ -17,7 +17,7 @@ import pytest # Tests ConfusionMatrix # =========================================================================== -from picarones.measurements.confusion import ( +from picarones.evaluation.metrics.confusion import ( EMPTY_CHAR, build_confusion_matrix, aggregate_confusion_matrices, @@ -146,7 +146,7 @@ class TestTopConfusedChars: # Tests LigatureScore # =========================================================================== -from picarones.measurements.char_scores import ( +from picarones.evaluation.metrics.char_scores import ( LIGATURE_TABLE, LigatureScore, DiacriticScore, @@ -288,7 +288,7 @@ class TestAggregateDiacriticScores: # Tests TaxonomyResult # =========================================================================== -from picarones.measurements.taxonomy import ( +from picarones.evaluation.metrics.taxonomy import ( TaxonomyResult, ERROR_CLASSES, classify_errors, @@ -395,7 +395,7 @@ class TestAggregateTaxonomy: # Tests StructureResult # =========================================================================== -from picarones.measurements.structure import ( +from picarones.evaluation.metrics.structure import ( StructureResult, analyze_structure, aggregate_structure, @@ -504,7 +504,7 @@ class TestAggregateStructure: # Tests ImageQualityResult # =========================================================================== -from picarones.measurements.image_quality import ( +from picarones.evaluation.metrics.image_quality import ( ImageQualityResult, generate_mock_quality_scores, aggregate_image_quality, diff --git a/tests/report/test_sprint72_worst_lines.py b/tests/report/test_sprint72_worst_lines.py index 7ab5642f10df07a912ba32f59b6625af3b83bde7..43084f973b3df0ffa5219af34a85d4eb0486ab06 100644 --- a/tests/report/test_sprint72_worst_lines.py +++ b/tests/report/test_sprint72_worst_lines.py @@ -27,7 +27,7 @@ from __future__ import annotations from dataclasses import dataclass, field from typing import Any -from picarones.measurements.worst_lines import WorstLineEntry, extract_worst_lines +from picarones.evaluation.metrics.worst_lines import WorstLineEntry, extract_worst_lines from picarones.reports_v2.html.renderers.worst_lines import build_worst_lines_table_html diff --git a/tests/report/test_sprint75_taxonomy_cooccurrence.py b/tests/report/test_sprint75_taxonomy_cooccurrence.py index b17e7bc5bf8158cfb0a00ebce888d97e2039b26f..0674dc18dc6ec74357b73835e4a6989053c74b0f 100644 --- a/tests/report/test_sprint75_taxonomy_cooccurrence.py +++ b/tests/report/test_sprint75_taxonomy_cooccurrence.py @@ -26,7 +26,7 @@ from pathlib import Path import pytest -from picarones.measurements.taxonomy_cooccurrence import ( +from picarones.evaluation.metrics.taxonomy_cooccurrence import ( compute_taxonomy_cooccurrence, ) from picarones.reports_v2.html.renderers.taxonomy_cooccurrence import ( diff --git a/tests/report/test_sprint76_taxonomy_intra_doc.py b/tests/report/test_sprint76_taxonomy_intra_doc.py index 661ae6ec0ab04b5093cd634e9d1d2645796e3df5..9b7052c64a2292aeddf3d8e421ddb1bd1943ed3e 100644 --- a/tests/report/test_sprint76_taxonomy_intra_doc.py +++ b/tests/report/test_sprint76_taxonomy_intra_doc.py @@ -26,7 +26,7 @@ from pathlib import Path import pytest -from picarones.measurements.taxonomy_intra_doc import ( +from picarones.evaluation.metrics.taxonomy_intra_doc import ( compute_taxonomy_position_heatmap, ) from picarones.reports_v2.html.renderers.taxonomy_intra_doc import ( diff --git a/tests/report/test_sprint77_taxonomy_comparison.py b/tests/report/test_sprint77_taxonomy_comparison.py index 7b4e5affdaa65b7435cbe206b4153d2279e48b62..d6862d8b1fe01610be5c943acd2ac9f1120ac77c 100644 --- a/tests/report/test_sprint77_taxonomy_comparison.py +++ b/tests/report/test_sprint77_taxonomy_comparison.py @@ -23,7 +23,7 @@ from __future__ import annotations import json from pathlib import Path -from picarones.measurements.taxonomy_comparison import ( +from picarones.evaluation.metrics.taxonomy_comparison import ( RECOVERABILITY, compare_taxonomies, ) @@ -91,7 +91,7 @@ class TestCompare: def test_recoverability_constant_complete(self) -> None: # Sanité : RECOVERABILITY couvre toutes les classes du module - from picarones.measurements.taxonomy import ERROR_CLASSES + from picarones.evaluation.metrics.taxonomy import ERROR_CLASSES for cls in ERROR_CLASSES: assert cls in RECOVERABILITY diff --git a/tests/report/test_sprint7_advanced_report.py b/tests/report/test_sprint7_advanced_report.py index a23900ebc3ff33f02e45989a70acd9677de5e035..2d2f4c690752f26597ff3d55a0c8a469cb3689b4 100644 --- a/tests/report/test_sprint7_advanced_report.py +++ b/tests/report/test_sprint7_advanced_report.py @@ -452,60 +452,60 @@ class TestCorrelationMatrix: class TestDifficultyScore: def test_returns_difficulty_score(self): - from picarones.measurements.difficulty import compute_difficulty_score + from picarones.evaluation.metrics.difficulty import compute_difficulty_score ds = compute_difficulty_score("doc1", "maiſtre Froiſſart", [0.1, 0.2, 0.3]) - from picarones.measurements.difficulty import DifficultyScore + from picarones.evaluation.metrics.difficulty import DifficultyScore assert isinstance(ds, DifficultyScore) def test_score_in_range(self): - from picarones.measurements.difficulty import compute_difficulty_score + from picarones.evaluation.metrics.difficulty import compute_difficulty_score ds = compute_difficulty_score("doc1", "hello world", [0.1, 0.2]) assert 0.0 <= ds.score <= 1.0 def test_more_variance_higher_score(self): - from picarones.measurements.difficulty import compute_difficulty_score + from picarones.evaluation.metrics.difficulty import compute_difficulty_score low_var = compute_difficulty_score("doc1", "hello", [0.1, 0.1, 0.1]) high_var = compute_difficulty_score("doc1", "hello", [0.0, 0.5, 1.0]) assert high_var.score > low_var.score def test_bad_quality_image_harder(self): - from picarones.measurements.difficulty import compute_difficulty_score + from picarones.evaluation.metrics.difficulty import compute_difficulty_score good_img = compute_difficulty_score("doc1", "hello", [0.1], image_quality_score=0.9) bad_img = compute_difficulty_score("doc1", "hello", [0.1], image_quality_score=0.1) assert bad_img.score > good_img.score def test_special_chars_increase_difficulty(self): - from picarones.measurements.difficulty import compute_difficulty_score + from picarones.evaluation.metrics.difficulty import compute_difficulty_score plain = compute_difficulty_score("doc1", "hello world plain text", [0.1]) heritage = compute_difficulty_score("doc1", "maiſtre Froiſſart ꝑ &", [0.1]) assert heritage.score > plain.score def test_components_present(self): - from picarones.measurements.difficulty import compute_difficulty_score + from picarones.evaluation.metrics.difficulty import compute_difficulty_score ds = compute_difficulty_score("doc1", "text", [0.1, 0.2]) assert hasattr(ds, "variance_component") assert hasattr(ds, "quality_component") assert hasattr(ds, "density_component") def test_as_dict_has_doc_id(self): - from picarones.measurements.difficulty import compute_difficulty_score + from picarones.evaluation.metrics.difficulty import compute_difficulty_score ds = compute_difficulty_score("folio_001", "text", [0.1]) d = ds.as_dict() assert d["doc_id"] == "folio_001" def test_as_dict_rounded(self): - from picarones.measurements.difficulty import compute_difficulty_score + from picarones.evaluation.metrics.difficulty import compute_difficulty_score ds = compute_difficulty_score("doc1", "text", [0.1]) d = ds.as_dict() assert isinstance(d["score"], float) def test_no_engines_gives_low_variance(self): - from picarones.measurements.difficulty import compute_difficulty_score + from picarones.evaluation.metrics.difficulty import compute_difficulty_score ds = compute_difficulty_score("doc1", "text", []) assert ds.cer_variance == 0.0 def test_difficulty_label(self): - from picarones.measurements.difficulty import difficulty_label + from picarones.evaluation.metrics.difficulty import difficulty_label assert difficulty_label(0.1) == "Facile" assert difficulty_label(0.35) == "Modéré" assert difficulty_label(0.6) == "Difficile" @@ -518,7 +518,7 @@ class TestDifficultyScore: class TestAllDifficulties: def test_returns_dict(self): - from picarones.measurements.difficulty import compute_all_difficulties + from picarones.evaluation.metrics.difficulty import compute_all_difficulties r = compute_all_difficulties( ["doc1", "doc2"], {"doc1": "hello", "doc2": "world"}, @@ -527,7 +527,7 @@ class TestAllDifficulties: assert isinstance(r, dict) def test_all_docs_present(self): - from picarones.measurements.difficulty import compute_all_difficulties + from picarones.evaluation.metrics.difficulty import compute_all_difficulties r = compute_all_difficulties( ["d1", "d2", "d3"], {"d1": "a", "d2": "b", "d3": "c"}, @@ -536,7 +536,7 @@ class TestAllDifficulties: assert set(r.keys()) == {"d1", "d2", "d3"} def test_scores_in_range(self): - from picarones.measurements.difficulty import compute_all_difficulties + from picarones.evaluation.metrics.difficulty import compute_all_difficulties r = compute_all_difficulties( ["d1", "d2"], {"d1": "maiſtre Jean", "d2": "simple text"}, @@ -546,7 +546,7 @@ class TestAllDifficulties: assert 0.0 <= ds.score <= 1.0 def test_with_image_quality(self): - from picarones.measurements.difficulty import compute_all_difficulties + from picarones.evaluation.metrics.difficulty import compute_all_difficulties r = compute_all_difficulties( ["d1"], {"d1": "text"}, @@ -558,12 +558,12 @@ class TestAllDifficulties: assert r["d1"].quality_component > 0.5 def test_empty_corpus(self): - from picarones.measurements.difficulty import compute_all_difficulties + from picarones.evaluation.metrics.difficulty import compute_all_difficulties r = compute_all_difficulties([], {}, {}) assert r == {} def test_missing_gt_handled(self): - from picarones.measurements.difficulty import compute_all_difficulties + from picarones.evaluation.metrics.difficulty import compute_all_difficulties r = compute_all_difficulties( ["d1"], {}, # GT manquante diff --git a/tests/report/test_sprint80_lexical_modernization.py b/tests/report/test_sprint80_lexical_modernization.py index c12bed7210374451e6ca06a4d4c11bbdd5a25043..ce109bf74d5b828c0a0433954b34808299746eac 100644 --- a/tests/report/test_sprint80_lexical_modernization.py +++ b/tests/report/test_sprint80_lexical_modernization.py @@ -27,7 +27,7 @@ from __future__ import annotations import json from pathlib import Path -from picarones.measurements.lexical_modernization import ( +from picarones.evaluation.metrics.lexical_modernization import ( aggregate_lexical_modernization, compute_lexical_modernization, top_modernized_tokens, diff --git a/tests/report/test_sprint82_levers.py b/tests/report/test_sprint82_levers.py index 53996633967c8e94525676fd9a1ed0468d188814..425b45b1470fe19280e39e4b3035c820ec09b1aa 100644 --- a/tests/report/test_sprint82_levers.py +++ b/tests/report/test_sprint82_levers.py @@ -19,7 +19,7 @@ import json import re from pathlib import Path -from picarones.measurements.levers import ( +from picarones.evaluation.metrics.levers import ( Lever, LeverImportance, LeverType, diff --git a/tests/report/test_sprint88_robustness_projection_html.py b/tests/report/test_sprint88_robustness_projection_html.py index 602c4acbf53e997231c9f440b2aac5d84b6afeed..18b39ae7890f3590864e76d43f2a3d6689ee8bdc 100644 --- a/tests/report/test_sprint88_robustness_projection_html.py +++ b/tests/report/test_sprint88_robustness_projection_html.py @@ -20,7 +20,7 @@ from __future__ import annotations import json from pathlib import Path -from picarones.measurements.robustness_projection import ( +from picarones.evaluation.metrics.robustness_projection import ( aggregate_projection_per_engine, project_robustness_on_corpus, ) diff --git a/tests/report/test_sprint89_specialization.py b/tests/report/test_sprint89_specialization.py index 92df35c4a6c079df198baf1531a2e371bc4c0612..66f7500bc82b125f98b313c08fad6b0521ef2edd 100644 --- a/tests/report/test_sprint89_specialization.py +++ b/tests/report/test_sprint89_specialization.py @@ -15,7 +15,7 @@ from __future__ import annotations import json from pathlib import Path -from picarones.measurements.specialization import ( +from picarones.evaluation.metrics.specialization import ( DEFAULT_THRESHOLDS, classify_specialization, compute_specialization_matrix, diff --git a/tests/report/test_sprint91_throughput.py b/tests/report/test_sprint91_throughput.py index c0dea8a5793e3daebf6031417f8b46c24c19a910..6c0a0ef275c9f44b6b75c4bcfe88ded5e086302c 100644 --- a/tests/report/test_sprint91_throughput.py +++ b/tests/report/test_sprint91_throughput.py @@ -20,11 +20,11 @@ from pathlib import Path import pytest -from picarones.measurements.marginal_cost import ( +from picarones.evaluation.metrics.marginal_cost import ( compute_marginal_cost, compute_marginal_cost_matrix, ) -from picarones.measurements.throughput import ( +from picarones.evaluation.metrics.throughput import ( aggregate_effective_throughput, compute_effective_throughput, ) diff --git a/tests/report/test_sprint92_longitudinal.py b/tests/report/test_sprint92_longitudinal.py index 1c0a1896764dfc359c5815292b5896beecc3cb05..e926b61d3d0a35fe4deaaced0a930146653c5d53 100644 --- a/tests/report/test_sprint92_longitudinal.py +++ b/tests/report/test_sprint92_longitudinal.py @@ -24,7 +24,7 @@ from pathlib import Path import pytest -from picarones.measurements.longitudinal import ( +from picarones.evaluation.metrics.longitudinal import ( compute_corpus_longitudinal, compute_engine_longitudinal, compute_linear_trend,