From cd2b8266d470e52a04eb0082e3bbe87a4b8efb44 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]=20requirement=20erplibre=20:=20d=C3=A9cla?= =?UTF-8?q?rer=20openpyxl,=20sauter=20sans=20lui?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three Transform data tests wrote an Excel workbook with openpyxl, which the .venv.erplibre requirements never declared, so the unit suite reported three errors on every install. openpyxl is now declared there. The tests skip when it cannot be imported in their own interpreter, since a venv built before this line still lacks it; the dedicated engine venv is not the right probe, as the tests write their workbook in-process. Checked: 707 Transform tests pass, and with openpyxl made unimportable the three are skipped, not errors. --- FR --- Trois tests de Transform data écrivaient un classeur Excel avec openpyxl, que les dépendances de .venv.erplibre ne déclaraient pas : la suite unitaire rendait trois erreurs sur toute installation. openpyxl y est désormais déclaré. Les tests se sautent quand il ne s'importe pas dans leur interpréteur, un venv bâti avant cette ligne ne l'ayant toujours pas ; le venv dédié du moteur n'est pas la bonne sonde, les tests écrivant leur classeur sur place. Vérifié : 707 tests de Transform passent, et openpyxl rendu inimportable, les trois sont sautés et non en erreur. Assisted-by: Claude Opus 5 --- requirement/erplibre_require-ments.txt | 5 +++++ script/data/external_file.py | 4 +--- script/todo/transform_menu.py | 2 +- script/todo/transform_setup.py | 9 +++++---- test/test_transform_external.py | 18 ++++++++++++++++++ 5 files changed, 30 insertions(+), 8 deletions(-) diff --git a/requirement/erplibre_require-ments.txt b/requirement/erplibre_require-ments.txt index 742caf8..dd21a07 100644 --- a/requirement/erplibre_require-ments.txt +++ b/requirement/erplibre_require-ments.txt @@ -37,6 +37,11 @@ rich # Il n'arrivait que par pykeepass / openupgradelib / odoo-module-migrator, donc # un jour où l'un d'eux s'en passe, il disparaît sans que rien ne le réclame. lxml +# Classeurs Excel de « Transform data », et les tests qui les éprouvent. Le +# moteur garde son venv dédié (script/todo/transform_setup.py) : un +# .venv.erplibre installé avant cette ligne n'a pas openpyxl, et le code ne +# l'importe donc jamais au niveau d'un module. +openpyxl python-dotenv python-dateutil unidecode diff --git a/script/data/external_file.py b/script/data/external_file.py index c1412cc..2ca5636 100644 --- a/script/data/external_file.py +++ b/script/data/external_file.py @@ -19,9 +19,7 @@ Les formats en pur stdlib — CSV, JSON, XML, et la détection de macros qui n'est qu'un `zipfile.namelist()` — tournent sous l'interpréteur du CLI. Excel et Access exigent un venv dédié. Le module doit donc s'importer sous les deux : AUCUN import de bibliothèque tierce au niveau du module, chacun -vit dans la fonction qui en a besoin. Les tests unitaires du dépôt tournent -sous `.venv.erplibre`, qui n'a pas openpyxl : un import au niveau du module -les ferait tomber tous, y compris ceux des règles pures. +vit dans la fonction qui en a besoin. Le canal de sortie ------------------ diff --git a/script/todo/transform_menu.py b/script/todo/transform_menu.py index 3c4c86a..a616390 100644 --- a/script/todo/transform_menu.py +++ b/script/todo/transform_menu.py @@ -971,7 +971,7 @@ class TransformMenuMixin: Le processus doit lire la source ET écrire la cible : il lui faut l'union des bibliothèques. La source seule laissait csv→xlsx - importer openpyxl sous l'interpréteur du CLI, qui ne l'a pas ; la + importer openpyxl sous l'interpréteur du CLI, qui peut ne pas l'avoir ; la cible seule enverrait un classeur au même interpréteur, qui ne sait pas le lire. """ diff --git a/script/todo/transform_setup.py b/script/todo/transform_setup.py index 1cb47e3..0ca8fda 100644 --- a/script/todo/transform_setup.py +++ b/script/todo/transform_setup.py @@ -4,10 +4,11 @@ """L'environnement de lecture des fichiers externes, posé à la demande. -Excel et Access exigent des bibliothèques qui ne sont dans aucun venv du -dépôt : `.venv.erplibre` porte l'outillage du CLI, le venv Odoo porte celui -d'Odoo, et charger l'un ou l'autre de ces lecteurs les mélangerait à un -sujet qui n'est pas le leur. D'où un venv dédié, bâti au premier besoin. +Excel et Access exigent des bibliothèques qu'aucun venv du dépôt ne porte à +coup sûr : `.venv.erplibre` porte l'outillage du CLI — openpyxl compris, +mais seulement depuis qu'il est dans ses dépendances —, le venv Odoo porte +celui d'Odoo, et le lecteur Access n'est dans aucun. D'où un venv dédié, +bâti au premier besoin. Les formats en pur stdlib n'en ont PAS besoin, et c'est ce que `available()` et `engine_python()` tiennent à la place des appelants : un diff --git a/test/test_transform_external.py b/test/test_transform_external.py index 83b4e56..3aa186c 100644 --- a/test/test_transform_external.py +++ b/test/test_transform_external.py @@ -6849,6 +6849,24 @@ class TestFuiteXlsx(unittest.TestCase): ) +def _openpyxl_ici(): + """Vrai si openpyxl s'importe dans CET interpréteur. + + Pas `transform_setup.available("xlsx")` : il répond vrai dès que le venv + dédié l'a, alors que ces tests écrivent leur classeur ici même. + """ + try: + import openpyxl # noqa: F401 + except ImportError: + return False + return True + + +@unittest.skipUnless( + _openpyxl_ici(), + "openpyxl absent de cet interpréteur : pip install -r" + " requirement/erplibre_require-ments.txt", +) class TestHorodatageDeLaCopie(unittest.TestCase): """La copie ne porte pas l'instant où elle a été tirée.