[FIX] requirement erplibre : déclarer openpyxl, sauter sans lui

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
This commit is contained in:
Mathieu Benoit 2026-09-16 02:59:01 -04:00
parent fb2f71477e
commit cd2b8266d4
5 changed files with 30 additions and 8 deletions

View file

@ -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

View file

@ -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
------------------

View file

@ -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.
"""

View file

@ -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

View file

@ -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.