From 7df58956eac26d00e429a35ab340ee5a70a66608 Mon Sep 17 00:00:00 2001 From: Mathieu Benoit Date: Wed, 16 Sep 2026 02:59:01 -0400 Subject: [PATCH] =?UTF-8?q?[FIX]=20tests=20assistant=20:=20juger=20la=20fr?= =?UTF-8?q?onti=C3=A8re=20dans=20un=20interpr=C3=A9teur=20neuf?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Six tests asserted that an assistant module does not import script.todo.todo by looking at sys.modules of the running process. Under the full suite another test had already imported todo, so all six failed whatever the module did. Each now imports its module in a fresh interpreter and reads the answer there. Checked: the six pass after test_todo_menu, the order that broke them, and a module made to import todo fails its test. --- FR --- Six tests affirmaient qu'un module de l'assistant n'importe pas script.todo.todo en regardant le sys.modules du processus en cours. Dans la suite complète, un autre test avait déjà importé todo : les six échouaient quoi que fasse le module. Chacun importe désormais son module dans un interpréteur neuf et y lit la réponse. Vérifié : les six passent après test_todo_menu, l'ordre qui les faisait tomber, et un module qu'on fait importer todo fait échouer son test. Assisted-by: Claude Opus 5 --- test/test_assistant_claude_sessions.py | 19 ++++++++++++++++++- test/test_assistant_context.py | 19 ++++++++++++++++++- test/test_assistant_gpt_loader.py | 19 ++++++++++++++++++- test/test_assistant_hosts.py | 19 ++++++++++++++++++- test/test_assistant_servers.py | 19 ++++++++++++++++++- test/test_assistant_sweep.py | 19 ++++++++++++++++++- 6 files changed, 108 insertions(+), 6 deletions(-) diff --git a/test/test_assistant_claude_sessions.py b/test/test_assistant_claude_sessions.py index 97c9478..cb439d9 100644 --- a/test/test_assistant_claude_sessions.py +++ b/test/test_assistant_claude_sessions.py @@ -31,6 +31,7 @@ from __future__ import annotations import json import os +import subprocess import sys import tempfile import unittest @@ -323,7 +324,23 @@ class LaFrontiere(unittest.TestCase): """Le paquet doit rester importable sans le CLI.""" def test_le_listage_n_importe_pas_todo(self): - self.assertNotIn("script.todo.todo", sys.modules) + # Dans un interpréteur NEUF : la suite complète importe todo par + # ailleurs, et le sys.modules de ce processus en garderait la trace + # quel que soit le module éprouvé ici. + sortie = subprocess.run( + [ + sys.executable, + "-c", + "import sys, script.todo.assistant.claude_sessions;" + " print('script.todo.todo' in sys.modules)", + ], + cwd=os.path.dirname(os.path.dirname(os.path.abspath(__file__))), + capture_output=True, + text=True, + timeout=60, + ) + self.assertEqual(sortie.returncode, 0, sortie.stderr) + self.assertEqual(sortie.stdout.strip(), "False") if __name__ == "__main__": diff --git a/test/test_assistant_context.py b/test/test_assistant_context.py index 1000848..ba61c5b 100644 --- a/test/test_assistant_context.py +++ b/test/test_assistant_context.py @@ -25,6 +25,7 @@ qu'il porte. from __future__ import annotations import os +import subprocess import sys import tempfile import unittest @@ -344,7 +345,23 @@ class LaFrontiere(unittest.TestCase): """Le paquet doit rester importable sans le CLI.""" def test_le_contexte_n_importe_pas_todo(self): - self.assertNotIn("script.todo.todo", sys.modules) + # Dans un interpréteur NEUF : la suite complète importe todo par + # ailleurs, et le sys.modules de ce processus en garderait la trace + # quel que soit le module éprouvé ici. + sortie = subprocess.run( + [ + sys.executable, + "-c", + "import sys, script.todo.assistant.context;" + " print('script.todo.todo' in sys.modules)", + ], + cwd=os.path.dirname(os.path.dirname(os.path.abspath(__file__))), + capture_output=True, + text=True, + timeout=60, + ) + self.assertEqual(sortie.returncode, 0, sortie.stderr) + self.assertEqual(sortie.stdout.strip(), "False") if __name__ == "__main__": diff --git a/test/test_assistant_gpt_loader.py b/test/test_assistant_gpt_loader.py index 169d56e..01e5dce 100644 --- a/test/test_assistant_gpt_loader.py +++ b/test/test_assistant_gpt_loader.py @@ -24,6 +24,7 @@ temporaires, et le répertoire personnel est détourné là où il compte. from __future__ import annotations import os +import subprocess import sys import tempfile import unittest @@ -394,7 +395,23 @@ class LaFrontiere(unittest.TestCase): """Le paquet doit rester importable sans le CLI.""" def test_le_chargeur_n_importe_pas_todo(self): - self.assertNotIn("script.todo.todo", sys.modules) + # Dans un interpréteur NEUF : la suite complète importe todo par + # ailleurs, et le sys.modules de ce processus en garderait la trace + # quel que soit le module éprouvé ici. + sortie = subprocess.run( + [ + sys.executable, + "-c", + "import sys, script.todo.assistant.gpt;" + " print('script.todo.todo' in sys.modules)", + ], + cwd=os.path.dirname(os.path.dirname(os.path.abspath(__file__))), + capture_output=True, + text=True, + timeout=60, + ) + self.assertEqual(sortie.returncode, 0, sortie.stderr) + self.assertEqual(sortie.stdout.strip(), "False") if __name__ == "__main__": diff --git a/test/test_assistant_hosts.py b/test/test_assistant_hosts.py index 3a93ed6..c2c82b3 100644 --- a/test/test_assistant_hosts.py +++ b/test/test_assistant_hosts.py @@ -40,6 +40,7 @@ niveau `.invalid` est réservé à cet usage, et « azurite », « obsidienne » import os import re +import subprocess import sys import unittest @@ -317,7 +318,23 @@ class LaFrontiere(unittest.TestCase): def test_les_sources_ne_tirent_pas_todo(self): """Importer `script.todo.todo` coûte près d'une seconde et imprime sur la sortie : le paquet doit rester importable seul.""" - self.assertNotIn("script.todo.todo", sys.modules) + # Dans un interpréteur NEUF : la suite complète importe todo par + # ailleurs, et le sys.modules de ce processus en garderait la trace + # quel que soit le module éprouvé ici. + sortie = subprocess.run( + [ + sys.executable, + "-c", + "import sys, script.todo.assistant.discover;" + " print('script.todo.todo' in sys.modules)", + ], + cwd=os.path.dirname(os.path.dirname(os.path.abspath(__file__))), + capture_output=True, + text=True, + timeout=60, + ) + self.assertEqual(sortie.returncode, 0, sortie.stderr) + self.assertEqual(sortie.stdout.strip(), "False") def test_aucun_analyseur_de_config_ssh_n_est_reecrit_ici(self): """`ssh -G` a raison sur les `Include`, les `Match`, l'héritage des diff --git a/test/test_assistant_servers.py b/test/test_assistant_servers.py index 3d89752..1a62658 100644 --- a/test/test_assistant_servers.py +++ b/test/test_assistant_servers.py @@ -28,6 +28,7 @@ n'y paraissent nulle part. """ import os +import subprocess import sys import unittest from pathlib import Path @@ -285,7 +286,23 @@ class LaFrontiere(unittest.TestCase): def test_le_registre_ne_tire_pas_todo(self): """Importer `script.todo.todo` coûte près d'une seconde et imprime sur la sortie : le paquet doit rester importable seul.""" - self.assertNotIn("script.todo.todo", sys.modules) + # Dans un interpréteur NEUF : la suite complète importe todo par + # ailleurs, et le sys.modules de ce processus en garderait la trace + # quel que soit le module éprouvé ici. + sortie = subprocess.run( + [ + sys.executable, + "-c", + "import sys, script.todo.assistant.servers;" + " print('script.todo.todo' in sys.modules)", + ], + cwd=os.path.dirname(os.path.dirname(os.path.abspath(__file__))), + capture_output=True, + text=True, + timeout=60, + ) + self.assertEqual(sortie.returncode, 0, sortie.stderr) + self.assertEqual(sortie.stdout.strip(), "False") if __name__ == "__main__": diff --git a/test/test_assistant_sweep.py b/test/test_assistant_sweep.py index d5ff2e1..88a1e14 100644 --- a/test/test_assistant_sweep.py +++ b/test/test_assistant_sweep.py @@ -35,6 +35,7 @@ paraissent nulle part ailleurs dans le dépôt. import os import re +import subprocess import sys import time import unittest @@ -354,7 +355,23 @@ class LaFrontiere(unittest.TestCase): def test_le_balayage_ne_tire_pas_todo(self): """Importer `script.todo.todo` coûte près d'une seconde et imprime sur la sortie : le paquet doit rester importable seul.""" - self.assertNotIn("script.todo.todo", sys.modules) + # Dans un interpréteur NEUF : la suite complète importe todo par + # ailleurs, et le sys.modules de ce processus en garderait la trace + # quel que soit le module éprouvé ici. + sortie = subprocess.run( + [ + sys.executable, + "-c", + "import sys, script.todo.assistant.discover, script.todo.assistant.fingerprint;" + " print('script.todo.todo' in sys.modules)", + ], + cwd=os.path.dirname(os.path.dirname(os.path.abspath(__file__))), + capture_output=True, + text=True, + timeout=60, + ) + self.assertEqual(sortie.returncode, 0, sortie.stderr) + self.assertEqual(sortie.stdout.strip(), "False") def test_aucun_asyncio_du_depot_n_est_utilise(self): """`AsyncioPool` enveloppe des sous-processus et non des sockets, et