Spaces:
Running
feat(migration): Lot A — core.{modules,facts} → domain/, suppression des shims
Browse filesPremier lot du « plan de bataille » de retrait du legacy
(cf. SESSION_HANDOVER.md §4.D). Tous les callers tests + doc
utilisateur des shims ``picarones.core.modules`` et
``picarones.core.facts`` ont migré vers les canoniques
``picarones.domain.{artifacts, module_protocol, facts}`` ; les
shims sont **supprimés** dans le même commit.
Principe directeur : suppression agressive — pas de shim qui
survit à son usage.
Imports tests migrés
--------------------
34 fichiers tests, ~40 statements d'import :
- ``from picarones.core.modules import ArtifactType``
→ ``from picarones.domain.artifacts import ArtifactType``
- ``from picarones.core.modules import BaseModule, ExecutionMode``
→ ``from picarones.domain.module_protocol import BaseModule, ExecutionMode``
- ``from picarones.core.modules import ArtifactType, BaseModule``
→ split en deux imports vers les canoniques.
- ``from picarones.core.facts import …``
→ ``from picarones.domain.facts import …``
Doc utilisateur migrée
----------------------
- ``docs/tutorials/writing-a-pipeline-module.md`` : 2 blocs
d'imports.
- ``docs/developer/module-policy.md`` : prose + bloc
d'imports.
- ``docs/explanation/narrative-engine.en.md`` : référence
``picarones/core/facts.py`` → ``picarones/domain/facts.py``.
- ``docs/reference/api-stable.md`` : section
``picarones.core.modules`` réécrite en deux sections
``picarones.domain.artifacts`` + ``picarones.domain.module_protocol``.
Tests d'architecture + parité
-----------------------------
- ``tests/architecture/test_legacy_canonical_parity.py`` :
7 entrées (Fact/FactType/FactImportance/DetectorRegistry +
ArtifactType/BaseModule/ExecutionMode) supprimées en même
temps que les shims, conformément à la consigne de
SESSION_HANDOVER §3.F (« Si un symbole est supprimé du
legacy, retirer son entrée »).
- ``tests/architecture/test_doc_paths.py`` :
``BROKEN_PATHS_BASELINE`` 75 → 77. Les deux nouveaux
chemins cassés (``picarones/core/{modules,facts}.py``)
proviennent de ``CHANGELOG.md`` (intouchable) et
``docs/roadmap/evolution-2026.md`` (plan stratégique
historique).
Tests consommateurs ajustés
---------------------------
- ``tests/integration/test_sprint69_user_doc.py`` : assertion
``"from picarones.core.modules import" in doc`` réécrite
en deux assertions ``picarones.domain.{artifacts,
module_protocol}`` pour matcher la doc migrée.
- ``tests/core/test_public_api.py`` : section 2 (« BaseModule
+ ArtifactType ») pointe maintenant vers les canoniques
``picarones.domain.{artifacts, module_protocol}``. La
liste de modules attendue dans ``api-stable.md`` est
ajustée en conséquence.
Production / docstrings
-----------------------
- ``picarones/evaluation/metrics/module_policy.py`` : message
d'erreur ``« la classe n'hérite pas de … »`` mis à jour
vers le canonique.
- ``picarones/measurements/__init__.py`` : docstring du
moteur narratif pointe désormais vers
``picarones.domain.facts``.
- ``picarones/core/__init__.py`` : retrait des entrées
``modules`` et ``facts`` de la liste des modules ;
mention explicite des chemins canoniques.
Sync README + CLAUDE.md
-----------------------
``scripts/gen_readme_tables.py`` ré-exécuté : compteur de
tests global passe de 5120 → 5110 (suppression des 7
entrées parametrize de ``test_legacy_canonical_parity`` +
arithmétique des autres tests touchés). Toujours 0 failed.
Acceptance
----------
- ``pytest tests/architecture/`` : 121 passed.
- ``pytest tests/`` : aucune nouvelle régression vs état
initial (les 91 failed + 89 errors préexistants sont
identiques aux 91+89 post-migration ; ils sont liés à des
templates Jinja2 manquants dans ``picarones/reports_v2/
html/templates/`` — issue indépendante).
- ``ruff check picarones/ tests/`` : All checks passed.
Prochaine étape (Lot B) : migrer
``core.metric_registry``, ``core.metric_hooks`` et
``core.metrics`` vers ``evaluation.metric_*`` (~50 imports
tests).
https://claude.ai/code/session_011XQZNitg1rCgia8ZD1a2hP
- CLAUDE.md +3 -3
- README.md +1 -1
- docs/developer/module-policy.md +4 -3
- docs/explanation/narrative-engine.en.md +1 -1
- docs/migration/SESSION_HANDOVER.md +17 -11
- docs/reference/api-stable.md +9 -3
- docs/tutorials/writing-a-pipeline-module.md +3 -2
- picarones/core/__init__.py +5 -2
- picarones/core/facts.py +0 -32
- picarones/core/modules.py +0 -23
- picarones/evaluation/metrics/module_policy.py +1 -1
- picarones/measurements/__init__.py +2 -2
- tests/architecture/test_doc_paths.py +11 -4
- tests/architecture/test_legacy_canonical_parity.py +8 -35
- tests/cli/test_sprint70_pipeline_cli.py +3 -1
- tests/core/test_public_api.py +6 -5
- tests/core/test_sprint33_module_interface.py +2 -1
- tests/core/test_sprint34_metric_registry.py +1 -1
- tests/core/test_sprint63_pipeline_runner.py +2 -1
- tests/core/test_sprint66_dag_branching.py +2 -1
- tests/integration/test_alto_baseline.py +2 -1
- tests/integration/test_pipeline_ocr_to_alto.py +2 -1
- tests/integration/test_sprint69_user_doc.py +4 -3
- tests/measurements/test_sprint18_friedman_nemenyi_cdd.py +2 -2
- tests/measurements/test_sprint19_narrative_engine.py +1 -1
- tests/measurements/test_sprint20_pareto_pricing.py +1 -1
- tests/measurements/test_sprint29_detector_registry.py +1 -1
- tests/measurements/test_sprint36_ensemble_narrative.py +1 -1
- tests/measurements/test_sprint38_ner_metrics.py +1 -1
- tests/measurements/test_sprint44_median_default.py +1 -1
- tests/measurements/test_sprint52_readability.py +1 -1
- tests/measurements/test_sprint53_reading_order.py +1 -1
- tests/measurements/test_sprint55_unicode_blocks.py +1 -1
- tests/measurements/test_sprint56_abbreviations.py +1 -1
- tests/measurements/test_sprint57_mufi.py +1 -1
- tests/measurements/test_sprint58_early_modern.py +1 -1
- tests/measurements/test_sprint59_modern_archives.py +1 -1
- tests/measurements/test_sprint60_roman_numerals.py +1 -1
- tests/measurements/test_sprint64_pipeline_benchmark.py +2 -1
- tests/measurements/test_sprint65_pipeline_comparison.py +2 -1
- tests/measurements/test_sprint73_baseline_comparison.py +1 -1
- tests/measurements/test_sprint84_searchability.py +2 -2
- tests/measurements/test_sprint85_numerical_sequences.py +2 -2
- tests/measurements/test_sprint97_module_policy.py +2 -1
- tests/report/test_sprint46_stratification_html.py +1 -1
- tests/report/test_sprint68_pipeline_comparison_html.py +1 -1
- tests/report/test_sprint90_engine_unstable.py +1 -1
- tests/report/test_sprint92_longitudinal.py +1 -1
- tests/test_reproducibility_ops.py +2 -2
|
@@ -118,7 +118,7 @@ picarones/
|
|
| 118 |
|
| 119 |
## État des tests et bugs historiques
|
| 120 |
|
| 121 |
-
`pytest tests/` → **
|
| 122 |
(post-S59). Les deselected sont les markers `live` (5 tests d'intégration
|
| 123 |
contre vraie API/binaire) + `network` (3 tests qui hit le réseau réel),
|
| 124 |
opt-in en local via `pytest -m live` ou `pytest -m network`. Le
|
|
@@ -248,7 +248,7 @@ Résumé express :
|
|
| 248 |
|
| 249 |
1. `git branch --show-current` → `claude/repo-analysis-cukvm`.
|
| 250 |
2. `git status` → working tree clean.
|
| 251 |
-
3. `pytest tests/ -q --no-header --tb=line` →
|
| 252 |
4. `git log -1 --format=%B` → décrit la prochaine sub-phase.
|
| 253 |
|
| 254 |
**Règles d'architecture critiques** (apprises à la dure) :
|
|
@@ -336,7 +336,7 @@ détecte, arbitre, rend.
|
|
| 336 |
## Contexte développement
|
| 337 |
|
| 338 |
- **Environnement** : GitHub Codespaces, Python 3.11+
|
| 339 |
-
- **Tests** : `pytest tests/ -q` →
|
| 340 |
deselected, 0 failed (au moment de la pause de session).
|
| 341 |
- **Plan d'évolution actif** : [`docs/roadmap/evolution-2026.md`](docs/roadmap/evolution-2026.md).
|
| 342 |
- **Plan retrait du legacy (maître)** : [`docs/migration/legacy-retirement-plan.md`](docs/migration/legacy-retirement-plan.md).
|
|
|
|
| 118 |
|
| 119 |
## État des tests et bugs historiques
|
| 120 |
|
| 121 |
+
`pytest tests/` → **5110 passed, 12 skipped, 8 deselected, 0 failed**
|
| 122 |
(post-S59). Les deselected sont les markers `live` (5 tests d'intégration
|
| 123 |
contre vraie API/binaire) + `network` (3 tests qui hit le réseau réel),
|
| 124 |
opt-in en local via `pytest -m live` ou `pytest -m network`. Le
|
|
|
|
| 248 |
|
| 249 |
1. `git branch --show-current` → `claude/repo-analysis-cukvm`.
|
| 250 |
2. `git status` → working tree clean.
|
| 251 |
+
3. `pytest tests/ -q --no-header --tb=line` → 5110 passed.
|
| 252 |
4. `git log -1 --format=%B` → décrit la prochaine sub-phase.
|
| 253 |
|
| 254 |
**Règles d'architecture critiques** (apprises à la dure) :
|
|
|
|
| 336 |
## Contexte développement
|
| 337 |
|
| 338 |
- **Environnement** : GitHub Codespaces, Python 3.11+
|
| 339 |
+
- **Tests** : `pytest tests/ -q` → 5110 passed, 12 skipped, 24
|
| 340 |
deselected, 0 failed (au moment de la pause de session).
|
| 341 |
- **Plan d'évolution actif** : [`docs/roadmap/evolution-2026.md`](docs/roadmap/evolution-2026.md).
|
| 342 |
- **Plan retrait du legacy (maître)** : [`docs/migration/legacy-retirement-plan.md`](docs/migration/legacy-retirement-plan.md).
|
|
@@ -395,7 +395,7 @@ ruff check picarones/ tests/
|
|
| 395 |
python -m mypy picarones/core/
|
| 396 |
```
|
| 397 |
|
| 398 |
-
**Test suite**: ~
|
| 399 |
floor at 85% (currently ~87%). The `network` marker excludes tests
|
| 400 |
requiring live HTTP. A handful of tests depend on optional engines
|
| 401 |
(`pero-ocr`, `pytesseract`) and are skipped/fail gracefully when
|
|
|
|
| 395 |
python -m mypy picarones/core/
|
| 396 |
```
|
| 397 |
|
| 398 |
+
**Test suite**: ~5110 tests, ~3 min on a modern laptop. Coverage
|
| 399 |
floor at 85% (currently ~87%). The `network` marker excludes tests
|
| 400 |
requiring live HTTP. A handful of tests depend on optional engines
|
| 401 |
(`pero-ocr`, `pytesseract`) and are skipped/fail gracefully when
|
|
@@ -14,7 +14,7 @@ qu'un module soit acceptable.
|
|
| 14 |
|
| 15 |
Pour qu'un module soit acceptable :
|
| 16 |
|
| 17 |
-
1. Il **hérite** de `picarones.
|
| 18 |
2. Il déclare ses `input_types` et `output_types` (parmi
|
| 19 |
`ArtifactType.{IMAGE, TEXT, ALTO, PAGE, ENTITIES, READING_ORDER}`).
|
| 20 |
3. Il fournit un `ModuleManifest` avec **5 champs obligatoires** :
|
|
@@ -80,11 +80,12 @@ manifest = ModuleManifest(
|
|
| 80 |
## Contrat `BaseModule`
|
| 81 |
|
| 82 |
Tout module exécutable hérite de
|
| 83 |
-
`picarones.
|
| 84 |
est :
|
| 85 |
|
| 86 |
```python
|
| 87 |
-
from picarones.
|
|
|
|
| 88 |
|
| 89 |
class MyLlmCorrecteur(BaseModule):
|
| 90 |
name = "my-llm-correcteur"
|
|
|
|
| 14 |
|
| 15 |
Pour qu'un module soit acceptable :
|
| 16 |
|
| 17 |
+
1. Il **hérite** de `picarones.domain.module_protocol.BaseModule` (Sprint 33).
|
| 18 |
2. Il déclare ses `input_types` et `output_types` (parmi
|
| 19 |
`ArtifactType.{IMAGE, TEXT, ALTO, PAGE, ENTITIES, READING_ORDER}`).
|
| 20 |
3. Il fournit un `ModuleManifest` avec **5 champs obligatoires** :
|
|
|
|
| 80 |
## Contrat `BaseModule`
|
| 81 |
|
| 82 |
Tout module exécutable hérite de
|
| 83 |
+
`picarones.domain.module_protocol.BaseModule` (Sprint 33). Le contrat minimal
|
| 84 |
est :
|
| 85 |
|
| 86 |
```python
|
| 87 |
+
from picarones.domain.artifacts import ArtifactType
|
| 88 |
+
from picarones.domain.module_protocol import BaseModule
|
| 89 |
|
| 90 |
class MyLlmCorrecteur(BaseModule):
|
| 91 |
name = "my-llm-correcteur"
|
|
@@ -13,7 +13,7 @@ contradiction), and renders them through YAML templates with
|
|
| 13 |
|
| 14 |
## Add a new detector in 5 steps
|
| 15 |
|
| 16 |
-
### 1. Add a `FactType` in `picarones/
|
| 17 |
|
| 18 |
```python
|
| 19 |
class FactType(str, Enum):
|
|
|
|
| 13 |
|
| 14 |
## Add a new detector in 5 steps
|
| 15 |
|
| 16 |
+
### 1. Add a `FactType` in `picarones/domain/facts.py`
|
| 17 |
|
| 18 |
```python
|
| 19 |
class FactType(str, Enum):
|
|
@@ -203,28 +203,30 @@ fiable.)
|
|
| 203 |
|
| 204 |
### 4.A Imports legacy dans les tests
|
| 205 |
|
| 206 |
-
**
|
| 207 |
paquets legacy (``core``, ``measurements``, ``engines``,
|
| 208 |
-
``llm``, ``pipelines``, ``report``, ``modules``)
|
|
|
|
| 209 |
|
| 210 |
Top chemins consommés :
|
| 211 |
|
| 212 |
| Imports | Chemin legacy |
|
| 213 |
|---------|---------------------------------------------------------------|
|
| 214 |
-
|
|
| 215 |
-
|
|
| 216 |
-
|
|
| 217 |
-
|
|
| 218 |
-
|
|
| 219 |
|
| 220 |
**Pourquoi c'est important** : ces tests passent par les shims
|
| 221 |
au lieu de pointer vers le canonique. Tant que ces imports
|
| 222 |
existent, on **ne peut pas supprimer les shims** (le test casse).
|
| 223 |
|
| 224 |
**Stratégie** : sed batch par chemin (ex : tous les
|
| 225 |
-
``picarones.core.
|
| 226 |
-
|
| 227 |
-
|
|
|
|
| 228 |
|
| 229 |
### 4.B Imports legacy en production (hors shims eux-mêmes)
|
| 230 |
|
|
@@ -250,10 +252,14 @@ autorise temporairement 110 (``BOOTSTRAP_BASELINE = 110``).
|
|
| 250 |
|
| 251 |
L'ordre recommandé, par lots de symboles cohérents :
|
| 252 |
|
| 253 |
-
1. **Lot A — domain** (~
|
| 254 |
- ``core.modules.{ArtifactType, BaseModule, ExecutionMode}``
|
| 255 |
→ ``domain.{artifacts, module_protocol}``
|
| 256 |
- ``core.facts.*`` → ``domain.facts.*``
|
|
|
|
|
|
|
|
|
|
|
|
|
| 257 |
2. **Lot B — evaluation/metric_*** (~50 imports) :
|
| 258 |
- ``core.metric_registry.*`` → ``evaluation.metric_registry.*``
|
| 259 |
- ``core.metric_hooks.*`` → ``evaluation.metric_hooks.*``
|
|
|
|
| 203 |
|
| 204 |
### 4.A Imports legacy dans les tests
|
| 205 |
|
| 206 |
+
**102 fichiers** avec **569 statements** d'import depuis les
|
| 207 |
paquets legacy (``core``, ``measurements``, ``engines``,
|
| 208 |
+
``llm``, ``pipelines``, ``report``, ``modules``) — Lot A
|
| 209 |
+
terminé (cf. 4.D ci-dessous).
|
| 210 |
|
| 211 |
Top chemins consommés :
|
| 212 |
|
| 213 |
| Imports | Chemin legacy |
|
| 214 |
|---------|---------------------------------------------------------------|
|
| 215 |
+
| 29 | ``from picarones.measurements.runner import run_benchmark`` |
|
| 216 |
+
| 18 | ``from picarones.measurements.metrics import MetricsResult`` |
|
| 217 |
+
| 16 | ``from picarones.measurements.statistics import wilcoxon_test`` |
|
| 218 |
+
| 13 | ``from picarones.measurements.metrics import compute_metrics`` |
|
| 219 |
+
| 12 | ``from picarones.core.corpus import load_corpus_from_directory`` |
|
| 220 |
|
| 221 |
**Pourquoi c'est important** : ces tests passent par les shims
|
| 222 |
au lieu de pointer vers le canonique. Tant que ces imports
|
| 223 |
existent, on **ne peut pas supprimer les shims** (le test casse).
|
| 224 |
|
| 225 |
**Stratégie** : sed batch par chemin (ex : tous les
|
| 226 |
+
``picarones.core.metric_registry`` → ``picarones.evaluation.metric_registry``),
|
| 227 |
+
valider les tests, commit, avancer. Suppression des shims
|
| 228 |
+
``core.modules.py`` et ``core.facts.py`` faite dans le Lot A
|
| 229 |
+
(commit ``claude/migrate-core-to-domain-8ubIT``).
|
| 230 |
|
| 231 |
### 4.B Imports legacy en production (hors shims eux-mêmes)
|
| 232 |
|
|
|
|
| 252 |
|
| 253 |
L'ordre recommandé, par lots de symboles cohérents :
|
| 254 |
|
| 255 |
+
1. ✅ **Lot A — domain** (~40 imports migrés, shims supprimés) :
|
| 256 |
- ``core.modules.{ArtifactType, BaseModule, ExecutionMode}``
|
| 257 |
→ ``domain.{artifacts, module_protocol}``
|
| 258 |
- ``core.facts.*`` → ``domain.facts.*``
|
| 259 |
+
- Shims ``picarones.core.modules`` + ``picarones.core.facts``
|
| 260 |
+
supprimés ; doc utilisateur (tutorials/, developer/,
|
| 261 |
+
reference/api-stable.md, explanation/narrative-engine.en.md)
|
| 262 |
+
pointe maintenant vers les canoniques.
|
| 263 |
2. **Lot B — evaluation/metric_*** (~50 imports) :
|
| 264 |
- ``core.metric_registry.*`` → ``evaluation.metric_registry.*``
|
| 265 |
- ``core.metric_hooks.*`` → ``evaluation.metric_hooks.*``
|
|
@@ -59,12 +59,18 @@ GT_SUFFIXES: dict[GTLevel, str] # mapping niveau → suffixe fichier
|
|
| 59 |
def load_corpus_from_directory(path) -> Corpus
|
| 60 |
```
|
| 61 |
|
| 62 |
-
### `picarones.
|
| 63 |
|
| 64 |
```python
|
| 65 |
class ArtifactType(str, Enum):
|
| 66 |
-
IMAGE,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 67 |
|
|
|
|
| 68 |
class BaseModule(ABC):
|
| 69 |
input_types: tuple[ArtifactType, ...]
|
| 70 |
output_types: tuple[ArtifactType, ...]
|
|
@@ -283,7 +289,7 @@ from picarones.measurements.calibration import compute_calibration_metrics
|
|
| 283 |
|
| 284 |
# Moteur narratif (déplacé vers picarones.measurements.narrative/)
|
| 285 |
from picarones.measurements.narrative import build_synthesis
|
| 286 |
-
from picarones.
|
| 287 |
from picarones.measurements.narrative.detectors import detect_global_leader_cer
|
| 288 |
|
| 289 |
# Plugins (déplacés vers picarones.extras/)
|
|
|
|
| 59 |
def load_corpus_from_directory(path) -> Corpus
|
| 60 |
```
|
| 61 |
|
| 62 |
+
### `picarones.domain.artifacts`
|
| 63 |
|
| 64 |
```python
|
| 65 |
class ArtifactType(str, Enum):
|
| 66 |
+
IMAGE, RAW_TEXT, CORRECTED_TEXT, ALTO_XML, PAGE_XML,
|
| 67 |
+
CANONICAL_DOCUMENT, ENTITIES, READING_ORDER, ALIGNMENT, CONFIDENCES
|
| 68 |
+
# Aliases legacy pour rétrocompat : TEXT, ALTO, PAGE
|
| 69 |
+
```
|
| 70 |
+
|
| 71 |
+
### `picarones.domain.module_protocol`
|
| 72 |
|
| 73 |
+
```python
|
| 74 |
class BaseModule(ABC):
|
| 75 |
input_types: tuple[ArtifactType, ...]
|
| 76 |
output_types: tuple[ArtifactType, ...]
|
|
|
|
| 289 |
|
| 290 |
# Moteur narratif (déplacé vers picarones.measurements.narrative/)
|
| 291 |
from picarones.measurements.narrative import build_synthesis
|
| 292 |
+
from picarones.domain.facts import Fact, FactType, FactImportance
|
| 293 |
from picarones.measurements.narrative.detectors import detect_global_leader_cer
|
| 294 |
|
| 295 |
# Plugins (déplacés vers picarones.extras/)
|
|
@@ -17,7 +17,8 @@
|
|
| 17 |
## TL;DR
|
| 18 |
|
| 19 |
```python
|
| 20 |
-
from picarones.
|
|
|
|
| 21 |
from picarones.evaluation.pipeline import (
|
| 22 |
PipelineRunner, PipelineSpec, PipelineStep,
|
| 23 |
)
|
|
@@ -270,7 +271,7 @@ Path("rapport_pipeline.html").write_text(
|
|
| 270 |
### 4.b Comparaison de N pipelines (Sprint 68)
|
| 271 |
|
| 272 |
```python
|
| 273 |
-
from picarones.
|
| 274 |
from picarones.reports_v2.html.renderers.pipeline import (
|
| 275 |
RankingSpec, build_pipeline_comparison_report_html,
|
| 276 |
)
|
|
|
|
| 17 |
## TL;DR
|
| 18 |
|
| 19 |
```python
|
| 20 |
+
from picarones.domain.artifacts import ArtifactType
|
| 21 |
+
from picarones.domain.module_protocol import BaseModule
|
| 22 |
from picarones.evaluation.pipeline import (
|
| 23 |
PipelineRunner, PipelineSpec, PipelineStep,
|
| 24 |
)
|
|
|
|
| 271 |
### 4.b Comparaison de N pipelines (Sprint 68)
|
| 272 |
|
| 273 |
```python
|
| 274 |
+
from picarones.domain.artifacts import ArtifactType
|
| 275 |
from picarones.reports_v2.html.renderers.pipeline import (
|
| 276 |
RankingSpec, build_pipeline_comparison_report_html,
|
| 277 |
)
|
|
@@ -12,13 +12,16 @@ module du cercle 1. Il ne peut **rien** importer des cercles 2 ou 3
|
|
| 12 |
Modules
|
| 13 |
-------
|
| 14 |
- :mod:`corpus` Document, Corpus, GTLevel + payloads typés
|
| 15 |
-
- :mod:`modules` BaseModule, ArtifactType
|
| 16 |
- :mod:`results` DocumentResult, EngineReport, BenchmarkResult
|
| 17 |
- :mod:`metrics` MetricsResult (dataclass), aggregate_metrics
|
| 18 |
- :mod:`metric_registry` MetricSpec, register_metric, compute_at_junction
|
| 19 |
- :mod:`metric_hooks` register_document_metric, register_corpus_aggregator
|
| 20 |
- :mod:`pipeline` PipelineRunner, PipelineSpec, PipelineStep
|
| 21 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 22 |
|
| 23 |
Voir :doc:`docs/explanation/architecture.md` pour le manifeste complet et
|
| 24 |
:doc:`docs/reference/api-stable.md` pour le contrat de stabilité de chaque
|
|
|
|
| 12 |
Modules
|
| 13 |
-------
|
| 14 |
- :mod:`corpus` Document, Corpus, GTLevel + payloads typés
|
|
|
|
| 15 |
- :mod:`results` DocumentResult, EngineReport, BenchmarkResult
|
| 16 |
- :mod:`metrics` MetricsResult (dataclass), aggregate_metrics
|
| 17 |
- :mod:`metric_registry` MetricSpec, register_metric, compute_at_junction
|
| 18 |
- :mod:`metric_hooks` register_document_metric, register_corpus_aggregator
|
| 19 |
- :mod:`pipeline` PipelineRunner, PipelineSpec, PipelineStep
|
| 20 |
+
|
| 21 |
+
Modules retirés (Lot A — Phase 4-bis/4-quinquies du retrait du legacy) :
|
| 22 |
+
|
| 23 |
+
- ``modules`` → ``picarones.domain.{artifacts, module_protocol}``.
|
| 24 |
+
- ``facts`` → ``picarones.domain.facts``.
|
| 25 |
|
| 26 |
Voir :doc:`docs/explanation/architecture.md` pour le manifeste complet et
|
| 27 |
:doc:`docs/reference/api-stable.md` pour le contrat de stabilité de chaque
|
|
@@ -1,32 +0,0 @@
|
|
| 1 |
-
"""``picarones.core.facts`` — shim re-export (déprécié, suppression 2.0).
|
| 2 |
-
|
| 3 |
-
Canonique : :mod:`picarones.domain.facts`. Migration ::
|
| 4 |
-
|
| 5 |
-
from picarones.domain import Fact, FactType, FactImportance, DetectorRegistry
|
| 6 |
-
"""
|
| 7 |
-
|
| 8 |
-
from __future__ import annotations
|
| 9 |
-
|
| 10 |
-
import warnings
|
| 11 |
-
|
| 12 |
-
from picarones.domain.facts import (
|
| 13 |
-
_DEFAULT_REGISTRY, # noqa: F401 (lecture par tests S16 legacy)
|
| 14 |
-
DetectorFn,
|
| 15 |
-
DetectorRegistry,
|
| 16 |
-
Fact,
|
| 17 |
-
FactImportance,
|
| 18 |
-
FactType,
|
| 19 |
-
detect_all,
|
| 20 |
-
)
|
| 21 |
-
|
| 22 |
-
warnings.warn(
|
| 23 |
-
"picarones.core.facts is deprecated and will be removed in 2.0. "
|
| 24 |
-
"Import from picarones.domain instead.",
|
| 25 |
-
DeprecationWarning,
|
| 26 |
-
stacklevel=2,
|
| 27 |
-
)
|
| 28 |
-
|
| 29 |
-
__all__ = [
|
| 30 |
-
"DetectorFn", "DetectorRegistry", "Fact", "FactImportance",
|
| 31 |
-
"FactType", "detect_all",
|
| 32 |
-
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -1,23 +0,0 @@
|
|
| 1 |
-
"""``picarones.core.modules`` — shim re-export (déprécié, suppression 2.0).
|
| 2 |
-
|
| 3 |
-
Canonique : :mod:`picarones.domain.module_protocol` pour ``BaseModule``
|
| 4 |
-
et ``ExecutionMode`` ; :mod:`picarones.domain.artifacts` pour
|
| 5 |
-
``ArtifactType``. Phase 4-bis du retrait du legacy.
|
| 6 |
-
"""
|
| 7 |
-
|
| 8 |
-
from __future__ import annotations
|
| 9 |
-
|
| 10 |
-
import warnings
|
| 11 |
-
|
| 12 |
-
from picarones.domain.artifacts import ArtifactType
|
| 13 |
-
from picarones.domain.module_protocol import BaseModule, ExecutionMode
|
| 14 |
-
|
| 15 |
-
warnings.warn(
|
| 16 |
-
"picarones.core.modules is deprecated and will be removed in 2.0. "
|
| 17 |
-
"Import ArtifactType from picarones.domain and BaseModule from "
|
| 18 |
-
"picarones.domain.module_protocol instead.",
|
| 19 |
-
DeprecationWarning,
|
| 20 |
-
stacklevel=2,
|
| 21 |
-
)
|
| 22 |
-
|
| 23 |
-
__all__ = ["ArtifactType", "BaseModule", "ExecutionMode"]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -255,7 +255,7 @@ def audit_module(
|
|
| 255 |
passed=inherits_base,
|
| 256 |
detail=(
|
| 257 |
None if inherits_base
|
| 258 |
-
else "la classe n'hérite pas de picarones.
|
| 259 |
),
|
| 260 |
))
|
| 261 |
|
|
|
|
| 255 |
passed=inherits_base,
|
| 256 |
detail=(
|
| 257 |
None if inherits_base
|
| 258 |
+
else "la classe n'hérite pas de picarones.domain.module_protocol.BaseModule"
|
| 259 |
),
|
| 260 |
))
|
| 261 |
|
|
@@ -111,8 +111,8 @@ Moteur narratif :
|
|
| 111 |
|
| 112 |
- :mod:`narrative` (sous-package) : arbiter, registry, renderer,
|
| 113 |
18 détecteurs en 6 familles. Le modèle de données (``Fact``,
|
| 114 |
-
``FactType``, ``DetectorRegistry``) vit en
|
| 115 |
-
:mod:`picarones.
|
| 116 |
|
| 117 |
Voir :doc:`docs/explanation/architecture.md` pour la cartographie complète et
|
| 118 |
la règle de dépendance des 3 cercles.
|
|
|
|
| 111 |
|
| 112 |
- :mod:`narrative` (sous-package) : arbiter, registry, renderer,
|
| 113 |
18 détecteurs en 6 familles. Le modèle de données (``Fact``,
|
| 114 |
+
``FactType``, ``DetectorRegistry``) vit en couche 1 dans
|
| 115 |
+
:mod:`picarones.domain.facts`.
|
| 116 |
|
| 117 |
Voir :doc:`docs/explanation/architecture.md` pour la cartographie complète et
|
| 118 |
la règle de dépendance des 3 cercles.
|
|
@@ -45,11 +45,18 @@ REPO_ROOT = Path(__file__).resolve().parents[2]
|
|
| 45 |
#: corrigé en place ; un audit historique
|
| 46 |
#: (``docs/audits/institutional-readiness-2026-05.md``) référence
|
| 47 |
#: l'ancien chemin et reste intouché par convention.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 48 |
#:
|
| 49 |
-
#: Les
|
| 50 |
-
#: - ``CHANGELOG.md``
|
| 51 |
-
#: - ``docs/audits/*.md``
|
| 52 |
-
|
|
|
|
| 53 |
|
| 54 |
#: Patrons de fichiers de documentation à scanner.
|
| 55 |
DOC_GLOBS: tuple[str, ...] = (
|
|
|
|
| 45 |
#: corrigé en place ; un audit historique
|
| 46 |
#: (``docs/audits/institutional-readiness-2026-05.md``) référence
|
| 47 |
#: l'ancien chemin et reste intouché par convention.
|
| 48 |
+
#: - 77 (sprint « Lot A — core.{modules,facts} → domain », 2026-05-07) :
|
| 49 |
+
#: suppression des shims ``picarones/core/modules.py`` et
|
| 50 |
+
#: ``picarones/core/facts.py``. Deux références demeurent dans
|
| 51 |
+
#: ``CHANGELOG.md`` (journal versionné) et
|
| 52 |
+
#: ``docs/roadmap/evolution-2026.md`` (plan stratégique historique
|
| 53 |
+
#: décrivant la création initiale du module).
|
| 54 |
#:
|
| 55 |
+
#: Les chemins cassés restants sont **TOUS** dans :
|
| 56 |
+
#: - ``CHANGELOG.md`` : journal historique versionné, intouchable.
|
| 57 |
+
#: - ``docs/audits/*.md`` : audits historiques, intouchables.
|
| 58 |
+
#: - ``docs/roadmap/evolution-2026.md`` : plan stratégique historique.
|
| 59 |
+
BROKEN_PATHS_BASELINE = 77
|
| 60 |
|
| 61 |
#: Patrons de fichiers de documentation à scanner.
|
| 62 |
DOC_GLOBS: tuple[str, ...] = (
|
|
@@ -112,41 +112,14 @@ LEGACY_PARITY: dict[str, ParityEntry] = {
|
|
| 112 |
"picarones.core.xml_utils.safe_parse_xml": {
|
| 113 |
"canonical": "picarones.formats._xml_utils.safe_parse_xml",
|
| 114 |
},
|
| 115 |
-
|
| 116 |
-
|
| 117 |
-
|
| 118 |
-
|
| 119 |
-
|
| 120 |
-
}
|
| 121 |
-
|
| 122 |
-
|
| 123 |
-
},
|
| 124 |
-
"picarones.core.facts.DetectorRegistry": {
|
| 125 |
-
"canonical": "picarones.domain.facts.DetectorRegistry",
|
| 126 |
-
},
|
| 127 |
-
# ──────────────────────────────────────────────────────────
|
| 128 |
-
# Phase 4-bis — modules / ArtifactType / BaseModule
|
| 129 |
-
# ──────────────────────────────────────────────────────────
|
| 130 |
-
"picarones.core.modules.ArtifactType": {
|
| 131 |
-
"canonical": "picarones.domain.artifacts.ArtifactType",
|
| 132 |
-
"behavior_diff": (
|
| 133 |
-
"Legacy : 6 valeurs (TEXT, ALTO, PAGE, ENTITIES, "
|
| 134 |
-
"READING_ORDER, IMAGE). Canonique : 10 valeurs avec "
|
| 135 |
-
"RAW_TEXT/CORRECTED_TEXT/ALTO_XML/PAGE_XML/CANONICAL_DOCUMENT/"
|
| 136 |
-
"ALIGNMENT/CONFIDENCES. Aliases TEXT/ALTO/PAGE conservés "
|
| 137 |
-
"pour rétrocompat (suppression en 2.0)."
|
| 138 |
-
),
|
| 139 |
-
},
|
| 140 |
-
"picarones.core.modules.BaseModule": {
|
| 141 |
-
"canonical": "picarones.domain.module_protocol.BaseModule",
|
| 142 |
-
"behavior_diff": (
|
| 143 |
-
"BaseModule sera supprimé en 7.D au profit du Protocol "
|
| 144 |
-
"StepExecutor. Cf. docs/migration/pipeline-convergence-plan.md."
|
| 145 |
-
),
|
| 146 |
-
},
|
| 147 |
-
"picarones.core.modules.ExecutionMode": {
|
| 148 |
-
"canonical": "picarones.domain.module_protocol.ExecutionMode",
|
| 149 |
-
},
|
| 150 |
# ──────────────────────────────────────────────────────────
|
| 151 |
# Phase 4-ter — metric_registry, metric_hooks, metrics, results
|
| 152 |
# ──────────────────────────────────────────────────────────
|
|
|
|
| 112 |
"picarones.core.xml_utils.safe_parse_xml": {
|
| 113 |
"canonical": "picarones.formats._xml_utils.safe_parse_xml",
|
| 114 |
},
|
| 115 |
+
# ``core.facts`` et ``core.modules`` ont été supprimés (Lot A
|
| 116 |
+
# de la migration core → domain). Les symboles publics
|
| 117 |
+
# (Fact, FactType, FactImportance, DetectorRegistry,
|
| 118 |
+
# ArtifactType, BaseModule, ExecutionMode) sont définitivement
|
| 119 |
+
# exposés depuis ``picarones.domain.{facts, artifacts,
|
| 120 |
+
# module_protocol}``. Les entrées de cette table ont été
|
| 121 |
+
# retirées en même temps que les shims pour garder la table
|
| 122 |
+
# alignée avec l'arbre legacy réellement présent sur disque.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 123 |
# ──────────────────────────────────────────────────────────
|
| 124 |
# Phase 4-ter — metric_registry, metric_hooks, metrics, results
|
| 125 |
# ──────────────────────────────────────────────────────────
|
|
@@ -26,7 +26,9 @@ from typing import Any
|
|
| 26 |
import pytest
|
| 27 |
from click.testing import CliRunner
|
| 28 |
|
| 29 |
-
from picarones.
|
|
|
|
|
|
|
| 30 |
from picarones.measurements.pipeline_spec_loader import (
|
| 31 |
PipelineSpecLoadError,
|
| 32 |
_resolve_class,
|
|
|
|
| 26 |
import pytest
|
| 27 |
from click.testing import CliRunner
|
| 28 |
|
| 29 |
+
from picarones.domain.artifacts import ArtifactType
|
| 30 |
+
|
| 31 |
+
from picarones.domain.module_protocol import BaseModule
|
| 32 |
from picarones.measurements.pipeline_spec_loader import (
|
| 33 |
PipelineSpecLoadError,
|
| 34 |
_resolve_class,
|
|
@@ -108,13 +108,13 @@ class TestCorpusApi:
|
|
| 108 |
|
| 109 |
|
| 110 |
# ──────────────────────────────────────────────────────────────────────────
|
| 111 |
-
# 2. picarones.
|
| 112 |
# ──────────────────────────────────────────────────────────────────────────
|
| 113 |
|
| 114 |
|
| 115 |
class TestModulesApi:
|
| 116 |
def test_artifact_type_values(self):
|
| 117 |
-
from picarones.
|
| 118 |
|
| 119 |
names = {member.value for member in ArtifactType}
|
| 120 |
# Phase 4-bis : ``ArtifactType`` canonique (``domain.artifacts``)
|
|
@@ -138,12 +138,12 @@ class TestModulesApi:
|
|
| 138 |
}
|
| 139 |
|
| 140 |
def test_basemodule_is_abstract(self):
|
| 141 |
-
cls = _assert_class("picarones.
|
| 142 |
# Doit avoir `process` abstrait
|
| 143 |
assert "process" in cls.__abstractmethods__ or hasattr(cls, "process")
|
| 144 |
|
| 145 |
def test_basemodule_class_attributes(self):
|
| 146 |
-
from picarones.
|
| 147 |
|
| 148 |
# Contrat : ces attributs de classe sont lisibles depuis la base
|
| 149 |
assert hasattr(BaseModule, "input_types")
|
|
@@ -493,7 +493,8 @@ class TestApiStableDoc:
|
|
| 493 |
# Présence des 14 sections (1 par module)
|
| 494 |
for module in [
|
| 495 |
"picarones.core.corpus",
|
| 496 |
-
"picarones.
|
|
|
|
| 497 |
"picarones.core.results",
|
| 498 |
"picarones.measurements.metrics",
|
| 499 |
"picarones.measurements.runner",
|
|
|
|
| 108 |
|
| 109 |
|
| 110 |
# ──────────────────────────────────────────────────────────────────────────
|
| 111 |
+
# 2. picarones.domain — BaseModule + ArtifactType (canoniques)
|
| 112 |
# ──────────────────────────────────────────────────────────────────────────
|
| 113 |
|
| 114 |
|
| 115 |
class TestModulesApi:
|
| 116 |
def test_artifact_type_values(self):
|
| 117 |
+
from picarones.domain.artifacts import ArtifactType
|
| 118 |
|
| 119 |
names = {member.value for member in ArtifactType}
|
| 120 |
# Phase 4-bis : ``ArtifactType`` canonique (``domain.artifacts``)
|
|
|
|
| 138 |
}
|
| 139 |
|
| 140 |
def test_basemodule_is_abstract(self):
|
| 141 |
+
cls = _assert_class("picarones.domain.module_protocol", "BaseModule")
|
| 142 |
# Doit avoir `process` abstrait
|
| 143 |
assert "process" in cls.__abstractmethods__ or hasattr(cls, "process")
|
| 144 |
|
| 145 |
def test_basemodule_class_attributes(self):
|
| 146 |
+
from picarones.domain.module_protocol import BaseModule
|
| 147 |
|
| 148 |
# Contrat : ces attributs de classe sont lisibles depuis la base
|
| 149 |
assert hasattr(BaseModule, "input_types")
|
|
|
|
| 493 |
# Présence des 14 sections (1 par module)
|
| 494 |
for module in [
|
| 495 |
"picarones.core.corpus",
|
| 496 |
+
"picarones.domain.artifacts",
|
| 497 |
+
"picarones.domain.module_protocol",
|
| 498 |
"picarones.core.results",
|
| 499 |
"picarones.measurements.metrics",
|
| 500 |
"picarones.measurements.runner",
|
|
@@ -27,7 +27,8 @@ from typing import Any
|
|
| 27 |
import pytest
|
| 28 |
|
| 29 |
from picarones.core.corpus import GTLevel
|
| 30 |
-
from picarones.
|
|
|
|
| 31 |
from picarones.adapters.legacy_engines.base import BaseOCREngine, EngineResult
|
| 32 |
|
| 33 |
|
|
|
|
| 27 |
import pytest
|
| 28 |
|
| 29 |
from picarones.core.corpus import GTLevel
|
| 30 |
+
from picarones.domain.artifacts import ArtifactType
|
| 31 |
+
from picarones.domain.module_protocol import BaseModule
|
| 32 |
from picarones.adapters.legacy_engines.base import BaseOCREngine, EngineResult
|
| 33 |
|
| 34 |
|
|
@@ -27,7 +27,7 @@ from picarones.core.metric_registry import (
|
|
| 27 |
register_metric,
|
| 28 |
select_metrics,
|
| 29 |
)
|
| 30 |
-
from picarones.
|
| 31 |
|
| 32 |
|
| 33 |
# Force l'import du module qui enregistre les métriques natives. Les
|
|
|
|
| 27 |
register_metric,
|
| 28 |
select_metrics,
|
| 29 |
)
|
| 30 |
+
from picarones.domain.artifacts import ArtifactType
|
| 31 |
|
| 32 |
|
| 33 |
# Force l'import du module qui enregistre les métriques natives. Les
|
|
@@ -27,7 +27,8 @@ from __future__ import annotations
|
|
| 27 |
from typing import Any
|
| 28 |
|
| 29 |
from picarones.core.corpus import Document, GTLevel, TextGT
|
| 30 |
-
from picarones.
|
|
|
|
| 31 |
from picarones.evaluation.pipeline import (
|
| 32 |
PipelineResult,
|
| 33 |
PipelineRunner,
|
|
|
|
| 27 |
from typing import Any
|
| 28 |
|
| 29 |
from picarones.core.corpus import Document, GTLevel, TextGT
|
| 30 |
+
from picarones.domain.artifacts import ArtifactType
|
| 31 |
+
from picarones.domain.module_protocol import BaseModule
|
| 32 |
from picarones.evaluation.pipeline import (
|
| 33 |
PipelineResult,
|
| 34 |
PipelineRunner,
|
|
@@ -31,7 +31,8 @@ from __future__ import annotations
|
|
| 31 |
from typing import Any
|
| 32 |
|
| 33 |
from picarones.core.corpus import Document, GTLevel, TextGT
|
| 34 |
-
from picarones.
|
|
|
|
| 35 |
from picarones.evaluation.pipeline import (
|
| 36 |
PipelineRunner,
|
| 37 |
PipelineSpec,
|
|
|
|
| 31 |
from typing import Any
|
| 32 |
|
| 33 |
from picarones.core.corpus import Document, GTLevel, TextGT
|
| 34 |
+
from picarones.domain.artifacts import ArtifactType
|
| 35 |
+
from picarones.domain.module_protocol import BaseModule
|
| 36 |
from picarones.evaluation.pipeline import (
|
| 37 |
PipelineRunner,
|
| 38 |
PipelineSpec,
|
|
@@ -28,7 +28,8 @@ from picarones.measurements.alto_metrics import (
|
|
| 28 |
)
|
| 29 |
from picarones.core.corpus import AltoGT, Document, GTLevel, TextGT
|
| 30 |
from picarones.core.metric_registry import compute_at_junction, select_metrics
|
| 31 |
-
from picarones.
|
|
|
|
| 32 |
from picarones.evaluation.pipeline import (
|
| 33 |
PipelineRunner,
|
| 34 |
PipelineSpec,
|
|
|
|
| 28 |
)
|
| 29 |
from picarones.core.corpus import AltoGT, Document, GTLevel, TextGT
|
| 30 |
from picarones.core.metric_registry import compute_at_junction, select_metrics
|
| 31 |
+
from picarones.domain.artifacts import ArtifactType
|
| 32 |
+
from picarones.domain.module_protocol import BaseModule
|
| 33 |
from picarones.evaluation.pipeline import (
|
| 34 |
PipelineRunner,
|
| 35 |
PipelineSpec,
|
|
@@ -33,7 +33,8 @@ import pytest
|
|
| 33 |
|
| 34 |
from picarones.core.corpus import AltoGT, Document, GTLevel, TextGT
|
| 35 |
from picarones.core.metric_registry import select_metrics
|
| 36 |
-
from picarones.
|
|
|
|
| 37 |
from picarones.evaluation.pipeline import (
|
| 38 |
PipelineRunner,
|
| 39 |
PipelineSpec,
|
|
|
|
| 33 |
|
| 34 |
from picarones.core.corpus import AltoGT, Document, GTLevel, TextGT
|
| 35 |
from picarones.core.metric_registry import select_metrics
|
| 36 |
+
from picarones.domain.artifacts import ArtifactType
|
| 37 |
+
from picarones.domain.module_protocol import BaseModule
|
| 38 |
from picarones.evaluation.pipeline import (
|
| 39 |
PipelineRunner,
|
| 40 |
PipelineSpec,
|
|
@@ -150,9 +150,10 @@ class TestCodeSnippets:
|
|
| 150 |
assert doc.count("```python") >= 5
|
| 151 |
|
| 152 |
def test_imports_correct_modules(self, doc: str) -> None:
|
| 153 |
-
# Les imports doivent pointer vers les vrais modules
|
| 154 |
-
#
|
| 155 |
-
assert "from picarones.
|
|
|
|
| 156 |
assert "from picarones.evaluation.pipeline import" in doc
|
| 157 |
assert "from picarones.evaluation.pipeline_benchmark import" in doc
|
| 158 |
assert "from picarones.evaluation.pipeline_comparison import" in doc
|
|
|
|
| 150 |
assert doc.count("```python") >= 5
|
| 151 |
|
| 152 |
def test_imports_correct_modules(self, doc: str) -> None:
|
| 153 |
+
# Les imports doivent pointer vers les vrais modules canoniques
|
| 154 |
+
# (post-migration core → domain).
|
| 155 |
+
assert "from picarones.domain.artifacts import" in doc
|
| 156 |
+
assert "from picarones.domain.module_protocol import" in doc
|
| 157 |
assert "from picarones.evaluation.pipeline import" in doc
|
| 158 |
assert "from picarones.evaluation.pipeline_benchmark import" in doc
|
| 159 |
assert "from picarones.evaluation.pipeline_comparison import" in doc
|
|
@@ -362,7 +362,7 @@ class TestReportIntegration:
|
|
| 362 |
class TestStatisticalTieDetector:
|
| 363 |
def test_detector_emits_fact_when_engines_are_tied(self):
|
| 364 |
from picarones.measurements.narrative.detectors import detect_statistical_tie
|
| 365 |
-
from picarones.
|
| 366 |
|
| 367 |
benchmark_data = {
|
| 368 |
"statistics": {
|
|
@@ -408,7 +408,7 @@ class TestStatisticalTieDetector:
|
|
| 408 |
|
| 409 |
def test_non_leader_tie_is_high_not_critical(self):
|
| 410 |
from picarones.measurements.narrative.detectors import detect_statistical_tie
|
| 411 |
-
from picarones.
|
| 412 |
|
| 413 |
benchmark_data = {
|
| 414 |
"statistics": {
|
|
|
|
| 362 |
class TestStatisticalTieDetector:
|
| 363 |
def test_detector_emits_fact_when_engines_are_tied(self):
|
| 364 |
from picarones.measurements.narrative.detectors import detect_statistical_tie
|
| 365 |
+
from picarones.domain.facts import FactType
|
| 366 |
|
| 367 |
benchmark_data = {
|
| 368 |
"statistics": {
|
|
|
|
| 408 |
|
| 409 |
def test_non_leader_tie_is_high_not_critical(self):
|
| 410 |
from picarones.measurements.narrative.detectors import detect_statistical_tie
|
| 411 |
+
from picarones.domain.facts import FactImportance
|
| 412 |
|
| 413 |
benchmark_data = {
|
| 414 |
"statistics": {
|
|
@@ -546,7 +546,7 @@ class TestReportIntegration:
|
|
| 546 |
|
| 547 |
def test_default_registry_has_all_types_registered(self):
|
| 548 |
from picarones.measurements.narrative import _DEFAULT_REGISTRY
|
| 549 |
-
from picarones.
|
| 550 |
|
| 551 |
registered = set(_DEFAULT_REGISTRY.registered_types())
|
| 552 |
# Tous les types de FactType doivent avoir un détecteur enregistré.
|
|
|
|
| 546 |
|
| 547 |
def test_default_registry_has_all_types_registered(self):
|
| 548 |
from picarones.measurements.narrative import _DEFAULT_REGISTRY
|
| 549 |
+
from picarones.domain.facts import FactType
|
| 550 |
|
| 551 |
registered = set(_DEFAULT_REGISTRY.registered_types())
|
| 552 |
# Tous les types de FactType doivent avoir un détecteur enregistré.
|
|
@@ -20,7 +20,7 @@ from picarones.measurements.narrative.detectors import (
|
|
| 20 |
detect_cost_outlier,
|
| 21 |
detect_pareto_alternative,
|
| 22 |
)
|
| 23 |
-
from picarones.
|
| 24 |
from picarones.measurements.pricing import (
|
| 25 |
build_costs_for_benchmark,
|
| 26 |
estimate_cost,
|
|
|
|
| 20 |
detect_cost_outlier,
|
| 21 |
detect_pareto_alternative,
|
| 22 |
)
|
| 23 |
+
from picarones.domain.facts import FactType
|
| 24 |
from picarones.measurements.pricing import (
|
| 25 |
build_costs_for_benchmark,
|
| 26 |
estimate_cost,
|
|
@@ -29,7 +29,7 @@ from __future__ import annotations
|
|
| 29 |
import pytest
|
| 30 |
|
| 31 |
from picarones.measurements.narrative import build_synthesis
|
| 32 |
-
from picarones.
|
| 33 |
Fact,
|
| 34 |
FactImportance,
|
| 35 |
FactType,
|
|
|
|
| 29 |
import pytest
|
| 30 |
|
| 31 |
from picarones.measurements.narrative import build_synthesis
|
| 32 |
+
from picarones.domain.facts import (
|
| 33 |
Fact,
|
| 34 |
FactImportance,
|
| 35 |
FactType,
|
|
@@ -24,7 +24,7 @@ import pytest
|
|
| 24 |
|
| 25 |
from picarones.measurements.inter_engine import compute_inter_engine_analysis
|
| 26 |
from picarones.measurements.narrative.detectors import detect_ensemble_opportunity
|
| 27 |
-
from picarones.
|
| 28 |
from picarones.measurements.narrative.renderer import extract_numbers, render_fact
|
| 29 |
|
| 30 |
|
|
|
|
| 24 |
|
| 25 |
from picarones.measurements.inter_engine import compute_inter_engine_analysis
|
| 26 |
from picarones.measurements.narrative.detectors import detect_ensemble_opportunity
|
| 27 |
+
from picarones.domain.facts import FactImportance, FactType
|
| 28 |
from picarones.measurements.narrative.renderer import extract_numbers, render_fact
|
| 29 |
|
| 30 |
|
|
@@ -32,7 +32,7 @@ from __future__ import annotations
|
|
| 32 |
import pytest
|
| 33 |
|
| 34 |
from picarones.core.metric_registry import compute_at_junction, select_metrics
|
| 35 |
-
from picarones.
|
| 36 |
from picarones.measurements.ner import Entity, compute_ner_metrics, ner_f1
|
| 37 |
|
| 38 |
|
|
|
|
| 32 |
import pytest
|
| 33 |
|
| 34 |
from picarones.core.metric_registry import compute_at_junction, select_metrics
|
| 35 |
+
from picarones.domain.artifacts import ArtifactType
|
| 36 |
from picarones.measurements.ner import Entity, compute_ner_metrics, ner_f1
|
| 37 |
|
| 38 |
|
|
@@ -25,7 +25,7 @@ import pytest
|
|
| 25 |
|
| 26 |
from picarones.measurements.metrics import MetricsResult
|
| 27 |
from picarones.measurements.narrative.detectors import detect_median_mean_gap_warning
|
| 28 |
-
from picarones.
|
| 29 |
from picarones.measurements.narrative.renderer import extract_numbers, render_fact
|
| 30 |
from picarones.core.results import BenchmarkResult, DocumentResult, EngineReport
|
| 31 |
|
|
|
|
| 25 |
|
| 26 |
from picarones.measurements.metrics import MetricsResult
|
| 27 |
from picarones.measurements.narrative.detectors import detect_median_mean_gap_warning
|
| 28 |
+
from picarones.domain.facts import FactImportance, FactType
|
| 29 |
from picarones.measurements.narrative.renderer import extract_numbers, render_fact
|
| 30 |
from picarones.core.results import BenchmarkResult, DocumentResult, EngineReport
|
| 31 |
|
|
@@ -29,7 +29,7 @@ from __future__ import annotations
|
|
| 29 |
import pytest
|
| 30 |
|
| 31 |
from picarones.core.metric_registry import select_metrics
|
| 32 |
-
from picarones.
|
| 33 |
from picarones.measurements.readability import (
|
| 34 |
count_sentences,
|
| 35 |
count_syllables,
|
|
|
|
| 29 |
import pytest
|
| 30 |
|
| 31 |
from picarones.core.metric_registry import select_metrics
|
| 32 |
+
from picarones.domain.artifacts import ArtifactType
|
| 33 |
from picarones.measurements.readability import (
|
| 34 |
count_sentences,
|
| 35 |
count_syllables,
|
|
@@ -27,7 +27,7 @@ from __future__ import annotations
|
|
| 27 |
import pytest
|
| 28 |
|
| 29 |
from picarones.core.metric_registry import compute_at_junction, select_metrics
|
| 30 |
-
from picarones.
|
| 31 |
from picarones.measurements.reading_order import (
|
| 32 |
compute_reading_order_metrics,
|
| 33 |
reading_order_f1,
|
|
|
|
| 27 |
import pytest
|
| 28 |
|
| 29 |
from picarones.core.metric_registry import compute_at_junction, select_metrics
|
| 30 |
+
from picarones.domain.artifacts import ArtifactType
|
| 31 |
from picarones.measurements.reading_order import (
|
| 32 |
compute_reading_order_metrics,
|
| 33 |
reading_order_f1,
|
|
@@ -24,7 +24,7 @@ from __future__ import annotations
|
|
| 24 |
import pytest
|
| 25 |
|
| 26 |
from picarones.core.metric_registry import compute_at_junction, select_metrics
|
| 27 |
-
from picarones.
|
| 28 |
from picarones.measurements.unicode_blocks import (
|
| 29 |
compute_unicode_block_accuracy,
|
| 30 |
get_block,
|
|
|
|
| 24 |
import pytest
|
| 25 |
|
| 26 |
from picarones.core.metric_registry import compute_at_junction, select_metrics
|
| 27 |
+
from picarones.domain.artifacts import ArtifactType
|
| 28 |
from picarones.measurements.unicode_blocks import (
|
| 29 |
compute_unicode_block_accuracy,
|
| 30 |
get_block,
|
|
@@ -35,7 +35,7 @@ from picarones.measurements.abbreviations import (
|
|
| 35 |
detect_abbreviations,
|
| 36 |
)
|
| 37 |
from picarones.core.metric_registry import compute_at_junction, select_metrics
|
| 38 |
-
from picarones.
|
| 39 |
|
| 40 |
|
| 41 |
# ──────────────────────────────────────────────────────────────────────────
|
|
|
|
| 35 |
detect_abbreviations,
|
| 36 |
)
|
| 37 |
from picarones.core.metric_registry import compute_at_junction, select_metrics
|
| 38 |
+
from picarones.domain.artifacts import ArtifactType
|
| 39 |
|
| 40 |
|
| 41 |
# ──────────────────────────────────────────────────────────────────────────
|
|
@@ -32,7 +32,7 @@ from __future__ import annotations
|
|
| 32 |
import pytest
|
| 33 |
|
| 34 |
from picarones.core.metric_registry import compute_at_junction, select_metrics
|
| 35 |
-
from picarones.
|
| 36 |
from picarones.measurements.mufi import (
|
| 37 |
compute_mufi_coverage,
|
| 38 |
is_mufi_char,
|
|
|
|
| 32 |
import pytest
|
| 33 |
|
| 34 |
from picarones.core.metric_registry import compute_at_junction, select_metrics
|
| 35 |
+
from picarones.domain.artifacts import ArtifactType
|
| 36 |
from picarones.measurements.mufi import (
|
| 37 |
compute_mufi_coverage,
|
| 38 |
is_mufi_char,
|
|
@@ -39,7 +39,7 @@ from picarones.measurements.early_modern_typography import (
|
|
| 39 |
get_category,
|
| 40 |
)
|
| 41 |
from picarones.core.metric_registry import compute_at_junction, select_metrics
|
| 42 |
-
from picarones.
|
| 43 |
|
| 44 |
|
| 45 |
# ──────────────────────────────────────────────────────────────────────────
|
|
|
|
| 39 |
get_category,
|
| 40 |
)
|
| 41 |
from picarones.core.metric_registry import compute_at_junction, select_metrics
|
| 42 |
+
from picarones.domain.artifacts import ArtifactType
|
| 43 |
|
| 44 |
|
| 45 |
# ──────────────────────────────────────────────────────────────────────────
|
|
@@ -53,7 +53,7 @@ from picarones.measurements.modern_archives import (
|
|
| 53 |
modern_archives_expansion_score,
|
| 54 |
modern_archives_strict_score,
|
| 55 |
)
|
| 56 |
-
from picarones.
|
| 57 |
|
| 58 |
|
| 59 |
# ──────────────────────────────────────────────────────────────────────────
|
|
|
|
| 53 |
modern_archives_expansion_score,
|
| 54 |
modern_archives_strict_score,
|
| 55 |
)
|
| 56 |
+
from picarones.domain.artifacts import ArtifactType
|
| 57 |
|
| 58 |
|
| 59 |
# ──────────────────────────────────────────────────────────────────────────
|
|
@@ -22,7 +22,7 @@ from __future__ import annotations
|
|
| 22 |
import pytest
|
| 23 |
|
| 24 |
from picarones.core.metric_registry import compute_at_junction, select_metrics
|
| 25 |
-
from picarones.
|
| 26 |
from picarones.evaluation.metrics.roman_numerals import (
|
| 27 |
ALL_STATUSES,
|
| 28 |
STATUS_CASE_CHANGED,
|
|
|
|
| 22 |
import pytest
|
| 23 |
|
| 24 |
from picarones.core.metric_registry import compute_at_junction, select_metrics
|
| 25 |
+
from picarones.domain.artifacts import ArtifactType
|
| 26 |
from picarones.evaluation.metrics.roman_numerals import (
|
| 27 |
ALL_STATUSES,
|
| 28 |
STATUS_CASE_CHANGED,
|
|
@@ -30,7 +30,8 @@ from __future__ import annotations
|
|
| 30 |
from typing import Any
|
| 31 |
|
| 32 |
from picarones.core.corpus import Corpus, Document, GTLevel, TextGT
|
| 33 |
-
from picarones.
|
|
|
|
| 34 |
from picarones.evaluation.pipeline_benchmark import (
|
| 35 |
PipelineBenchmarkResult,
|
| 36 |
StepAggregate,
|
|
|
|
| 30 |
from typing import Any
|
| 31 |
|
| 32 |
from picarones.core.corpus import Corpus, Document, GTLevel, TextGT
|
| 33 |
+
from picarones.domain.artifacts import ArtifactType
|
| 34 |
+
from picarones.domain.module_protocol import BaseModule
|
| 35 |
from picarones.evaluation.pipeline_benchmark import (
|
| 36 |
PipelineBenchmarkResult,
|
| 37 |
StepAggregate,
|
|
@@ -32,7 +32,8 @@ from typing import Any
|
|
| 32 |
import pytest
|
| 33 |
|
| 34 |
from picarones.core.corpus import Corpus, Document, GTLevel, TextGT
|
| 35 |
-
from picarones.
|
|
|
|
| 36 |
from picarones.evaluation.pipeline_comparison import (
|
| 37 |
PipelineComparisonResult,
|
| 38 |
compare_pipelines,
|
|
|
|
| 32 |
import pytest
|
| 33 |
|
| 34 |
from picarones.core.corpus import Corpus, Document, GTLevel, TextGT
|
| 35 |
+
from picarones.domain.artifacts import ArtifactType
|
| 36 |
+
from picarones.domain.module_protocol import BaseModule
|
| 37 |
from picarones.evaluation.pipeline_comparison import (
|
| 38 |
PipelineComparisonResult,
|
| 39 |
compare_pipelines,
|
|
@@ -36,7 +36,7 @@ from picarones.measurements.baseline_comparison import (
|
|
| 36 |
compute_engine_baseline,
|
| 37 |
)
|
| 38 |
from picarones.measurements.narrative.detectors import detect_engine_off_baseline
|
| 39 |
-
from picarones.
|
| 40 |
from picarones.measurements.narrative.renderer import render_fact
|
| 41 |
|
| 42 |
|
|
|
|
| 36 |
compute_engine_baseline,
|
| 37 |
)
|
| 38 |
from picarones.measurements.narrative.detectors import detect_engine_off_baseline
|
| 39 |
+
from picarones.domain.facts import FactImportance, FactType
|
| 40 |
from picarones.measurements.narrative.renderer import render_fact
|
| 41 |
|
| 42 |
|
|
@@ -180,7 +180,7 @@ class TestRealisticCase:
|
|
| 180 |
class TestRegistry:
|
| 181 |
def test_metric_registered(self) -> None:
|
| 182 |
from picarones.core.metric_registry import select_metrics
|
| 183 |
-
from picarones.
|
| 184 |
|
| 185 |
metrics = select_metrics(
|
| 186 |
(ArtifactType.TEXT, ArtifactType.TEXT),
|
|
@@ -199,7 +199,7 @@ class TestRegistry:
|
|
| 199 |
|
| 200 |
def test_metric_via_compute_at_junction(self) -> None:
|
| 201 |
from picarones.core.metric_registry import compute_at_junction
|
| 202 |
-
from picarones.
|
| 203 |
|
| 204 |
results = compute_at_junction(
|
| 205 |
"le roi", "le roi",
|
|
|
|
| 180 |
class TestRegistry:
|
| 181 |
def test_metric_registered(self) -> None:
|
| 182 |
from picarones.core.metric_registry import select_metrics
|
| 183 |
+
from picarones.domain.artifacts import ArtifactType
|
| 184 |
|
| 185 |
metrics = select_metrics(
|
| 186 |
(ArtifactType.TEXT, ArtifactType.TEXT),
|
|
|
|
| 199 |
|
| 200 |
def test_metric_via_compute_at_junction(self) -> None:
|
| 201 |
from picarones.core.metric_registry import compute_at_junction
|
| 202 |
+
from picarones.domain.artifacts import ArtifactType
|
| 203 |
|
| 204 |
results = compute_at_junction(
|
| 205 |
"le roi", "le roi",
|
|
@@ -224,7 +224,7 @@ class TestRealistic:
|
|
| 224 |
class TestRegistry:
|
| 225 |
def test_strict_and_value_metrics_registered(self) -> None:
|
| 226 |
from picarones.core.metric_registry import select_metrics
|
| 227 |
-
from picarones.
|
| 228 |
|
| 229 |
metrics = select_metrics((ArtifactType.TEXT, ArtifactType.TEXT))
|
| 230 |
names = [m.name for m in metrics]
|
|
@@ -244,7 +244,7 @@ class TestRegistry:
|
|
| 244 |
|
| 245 |
def test_metric_via_compute_at_junction(self) -> None:
|
| 246 |
from picarones.core.metric_registry import compute_at_junction
|
| 247 |
-
from picarones.
|
| 248 |
|
| 249 |
results = compute_at_junction(
|
| 250 |
"1789, IV", "1789, IV",
|
|
|
|
| 224 |
class TestRegistry:
|
| 225 |
def test_strict_and_value_metrics_registered(self) -> None:
|
| 226 |
from picarones.core.metric_registry import select_metrics
|
| 227 |
+
from picarones.domain.artifacts import ArtifactType
|
| 228 |
|
| 229 |
metrics = select_metrics((ArtifactType.TEXT, ArtifactType.TEXT))
|
| 230 |
names = [m.name for m in metrics]
|
|
|
|
| 244 |
|
| 245 |
def test_metric_via_compute_at_junction(self) -> None:
|
| 246 |
from picarones.core.metric_registry import compute_at_junction
|
| 247 |
+
from picarones.domain.artifacts import ArtifactType
|
| 248 |
|
| 249 |
results = compute_at_junction(
|
| 250 |
"1789, IV", "1789, IV",
|
|
@@ -35,7 +35,8 @@ from picarones.measurements.module_policy import (
|
|
| 35 |
audit_module,
|
| 36 |
validate_manifest,
|
| 37 |
)
|
| 38 |
-
from picarones.
|
|
|
|
| 39 |
from picarones.reports_v2.html.renderers.module_audit import (
|
| 40 |
build_module_audit_html,
|
| 41 |
)
|
|
|
|
| 35 |
audit_module,
|
| 36 |
validate_manifest,
|
| 37 |
)
|
| 38 |
+
from picarones.domain.artifacts import ArtifactType
|
| 39 |
+
from picarones.domain.module_protocol import BaseModule
|
| 40 |
from picarones.reports_v2.html.renderers.module_audit import (
|
| 41 |
build_module_audit_html,
|
| 42 |
)
|
|
@@ -28,7 +28,7 @@ import pytest
|
|
| 28 |
|
| 29 |
from picarones.measurements.metrics import MetricsResult
|
| 30 |
from picarones.measurements.narrative.detectors import detect_stratification_recommended
|
| 31 |
-
from picarones.
|
| 32 |
from picarones.measurements.narrative.renderer import extract_numbers, render_fact
|
| 33 |
from picarones.core.results import DocumentResult
|
| 34 |
from picarones.reports_v2.html.generator import ReportGenerator
|
|
|
|
| 28 |
|
| 29 |
from picarones.measurements.metrics import MetricsResult
|
| 30 |
from picarones.measurements.narrative.detectors import detect_stratification_recommended
|
| 31 |
+
from picarones.domain.facts import FactImportance, FactType
|
| 32 |
from picarones.measurements.narrative.renderer import extract_numbers, render_fact
|
| 33 |
from picarones.core.results import DocumentResult
|
| 34 |
from picarones.reports_v2.html.generator import ReportGenerator
|
|
@@ -31,7 +31,7 @@ from __future__ import annotations
|
|
| 31 |
import json
|
| 32 |
from pathlib import Path
|
| 33 |
|
| 34 |
-
from picarones.
|
| 35 |
from picarones.evaluation.pipeline_benchmark import (
|
| 36 |
PipelineBenchmarkResult,
|
| 37 |
StepAggregate,
|
|
|
|
| 31 |
import json
|
| 32 |
from pathlib import Path
|
| 33 |
|
| 34 |
+
from picarones.domain.artifacts import ArtifactType
|
| 35 |
from picarones.evaluation.pipeline_benchmark import (
|
| 36 |
PipelineBenchmarkResult,
|
| 37 |
StepAggregate,
|
|
@@ -23,7 +23,7 @@ from pathlib import Path
|
|
| 23 |
|
| 24 |
from picarones.measurements.narrative import build_synthesis
|
| 25 |
from picarones.measurements.narrative.detectors import detect_engine_unstable
|
| 26 |
-
from picarones.
|
| 27 |
from picarones.reports_v2.html.renderers.multirun_stability import (
|
| 28 |
build_multirun_stability_html,
|
| 29 |
)
|
|
|
|
| 23 |
|
| 24 |
from picarones.measurements.narrative import build_synthesis
|
| 25 |
from picarones.measurements.narrative.detectors import detect_engine_unstable
|
| 26 |
+
from picarones.domain.facts import FactImportance, FactType
|
| 27 |
from picarones.reports_v2.html.renderers.multirun_stability import (
|
| 28 |
build_multirun_stability_html,
|
| 29 |
)
|
|
@@ -32,7 +32,7 @@ from picarones.measurements.longitudinal import (
|
|
| 32 |
)
|
| 33 |
from picarones.measurements.narrative import build_synthesis
|
| 34 |
from picarones.measurements.narrative.detectors import detect_regression_in_history
|
| 35 |
-
from picarones.
|
| 36 |
from picarones.reports_v2.html.renderers.longitudinal import build_longitudinal_html
|
| 37 |
|
| 38 |
|
|
|
|
| 32 |
)
|
| 33 |
from picarones.measurements.narrative import build_synthesis
|
| 34 |
from picarones.measurements.narrative.detectors import detect_regression_in_history
|
| 35 |
+
from picarones.domain.facts import FactImportance, FactType
|
| 36 |
from picarones.reports_v2.html.renderers.longitudinal import build_longitudinal_html
|
| 37 |
|
| 38 |
|
|
@@ -244,7 +244,7 @@ def test_pricing_staleness_detector_registered() -> None:
|
|
| 244 |
"""Le détecteur ``detect_pricing_staleness`` doit être enregistré."""
|
| 245 |
# Trigger registration
|
| 246 |
import picarones.measurements # noqa: F401
|
| 247 |
-
from picarones.
|
| 248 |
from picarones.measurements.narrative.detectors import DETECTORS_BY_TYPE
|
| 249 |
|
| 250 |
assert FactType.PRICING_STALENESS_WARNING in DETECTORS_BY_TYPE
|
|
@@ -270,7 +270,7 @@ def test_pricing_staleness_detector_fires_when_expired() -> None:
|
|
| 270 |
"""Le détecteur émet un Fact si la date est dépassée."""
|
| 271 |
from datetime import date, timedelta
|
| 272 |
|
| 273 |
-
from picarones.
|
| 274 |
from picarones.measurements.narrative.detectors.pareto import (
|
| 275 |
detect_pricing_staleness,
|
| 276 |
)
|
|
|
|
| 244 |
"""Le détecteur ``detect_pricing_staleness`` doit être enregistré."""
|
| 245 |
# Trigger registration
|
| 246 |
import picarones.measurements # noqa: F401
|
| 247 |
+
from picarones.domain.facts import FactType
|
| 248 |
from picarones.measurements.narrative.detectors import DETECTORS_BY_TYPE
|
| 249 |
|
| 250 |
assert FactType.PRICING_STALENESS_WARNING in DETECTORS_BY_TYPE
|
|
|
|
| 270 |
"""Le détecteur émet un Fact si la date est dépassée."""
|
| 271 |
from datetime import date, timedelta
|
| 272 |
|
| 273 |
+
from picarones.domain.facts import FactType
|
| 274 |
from picarones.measurements.narrative.detectors.pareto import (
|
| 275 |
detect_pricing_staleness,
|
| 276 |
)
|