Cours de Python / Construire un paquet et vérifier son installation avec un wheel
Un projet Python peut déclarer ses informations et son système de construction dans pyproject.toml, puis produire un fichier wheel installable. Pour vérifier le paquet réellement distribué, installez ce fichier dans un environnement neuf et testez-le depuis un dossier extérieur aux sources.
Séparer le nom de distribution et le paquet importé
Dans cet exercice, la distribution installable s’appelle expensekit-demo, tandis que le paquet importé s’appelle expensekit. Un nom de distribution peut contenir un trait d’union sans que ce soit le nom à écrire après import. Le fichier wheel est une archive de distribution construite pour l’installation ; l’archive source, ou sdist, fournit les sources nécessaires à une construction.
Le dossier src sépare les sources du répertoire racine du projet. Cette disposition aide à ne pas confondre une importation directe des fichiers de travail avec une installation correcte. La documentation setuptools sur la découverte des paquets présente cette organisation.
Utilisez Python 3.12 ou une version ultérieure, comme le déclare le projet. Créez un nouveau dossier d’exercice et un environnement de construction dédié. Le cours sur les environnements virtuels et pip explique leur isolation. Les noms choisis ici servent à une démonstration locale : ils ne prouvent ni la disponibilité ni la propriété d’un nom sur un dépôt public.
Créer tous les fichiers du projet
Dans le dossier racine du projet, créez le sous-dossier src/expensekit. Enregistrez en UTF-8 les deux fichiers Python et la configuration ci-dessous.
Contenu complet de src/expensekit/__init__.py :
def total(amounts):
if any(type(x) is not int or x < 0 for x in amounts):
raise ValueError("invalid amount")
return sum(amounts)
Cette fonction de démonstration reçoit une liste d’entiers positifs ou nuls et refuse les booléens, chaînes et valeurs négatives. Son résultat pour une liste vide est zéro. Ne généralisez pas ce contrat à un itérateur à usage unique sans revoir la validation et l’addition, qui parcourent les valeurs séparément.
Contenu complet de src/expensekit/cli.py :
import argparse
from . import total
def main():
parser = argparse.ArgumentParser()
parser.add_argument("amounts", type=int, nargs="+")
args = parser.parse_args()
print(total(args.amounts))
if __name__ == "__main__":
main()
L’import relatif from . import total retrouve la fonction du paquet. main définit l’interface de commande et la protection de fin permet d’importer le module sans déclencher l’analyse des arguments.
Contenu complet de pyproject.toml, à la racine du projet :
[build-system]
requires = ["setuptools>=68"]
build-backend = "setuptools.build_meta"
[project]
name = "expensekit-demo"
version = "0.1.0"
description = "Local expense sum example"
requires-python = ">=3.12"
[project.scripts]
expense-total = "expensekit.cli:main"
[tool.setuptools.packages.find]
where = ["src"]
[build-system] choisit setuptools comme backend et déclare les outils nécessaires à la construction. [project] fournit le nom, la version et la condition sur Python. [project.scripts] déclare le nom de commande expense-total relié à expensekit.cli:main ; le réglage de recherche indique que les paquets sont sous src. Le guide officiel de pyproject.toml distingue ces tables.
Construire puis installer dans un environnement neuf
Dans l’environnement de construction, ouvrez le terminal dans le dossier contenant pyproject.toml. Installez l’outil et construisez les distributions :
python -m pip install build
python -m build
Le frontend build utilise le backend déclaré et peut télécharger les dépendances de construction dans un environnement isolé. Le dossier dist doit contenir expensekit_demo-0.1.0-py3-none-any.whl et expensekit_demo-0.1.0.tar.gz. Les noms de fichiers de distribution sont normalisés : les traits d’union du nom du projet n’apparaissent pas nécessairement tels quels dans ces noms.
Créez ensuite un environnement de vérification neuf, séparé de celui qui contient les outils de construction :
python -m venv .venv-check
Le chemin .venv-check est relatif au dossier courant. N’utilisez pas le dossier d’un ancien environnement si vous voulez vérifier une installation neuve ; choisissez un autre nom et adaptez les chemins en cas de collision. La référence de venv explique les interpréteurs propres aux environnements.
Sous Windows PowerShell, installez le wheel avec l’interpréteur de vérification :
.\.venv-check\Scripts\python.exe -m pip install dist/expensekit_demo-0.1.0-py3-none-any.whl
Sous macOS ou Ubuntu, utilisez :
.venv-check/bin/python -m pip install dist/expensekit_demo-0.1.0-py3-none-any.whl
Ces chemins doivent désigner le nouvel environnement. Une installation réussie dans l’environnement de construction ne suffit pas à prouver que le paquet est complet. Le tutoriel officiel de construction des projets Python décrit le processus et les fichiers produits.
Avant de changer de dossier, activez l’environnement de vérification ou repérez le chemin absolu de son interpréteur. Déplacez-vous ensuite dans un dossier vide extérieur au projet. Pour les commandes suivantes, python doit être celui de .venv-check ; si vous n’avez pas activé l’environnement, remplacez ce nom par le chemin absolu de cet exécutable.
python -c "from expensekit import total; print(total([3500,8000,2500]))"
python -m expensekit.cli 3500 8000 2500
Les deux commandes doivent afficher 14000. Vérifiez aussi expense-total 3500 8000 2500 dans l’environnement activé, ou appelez son exécutable par chemin : il doit afficher le même total. Le cours sur les points d’entrée des paquets explique la relation entre import, exécution de module et commande installée.
Diagnostiquer une installation incomplète et préparer une vraie publication
Si l’import fonctionne seulement depuis les sources, contrôlez l’interpréteur réellement utilisé, le paquet installé et le contenu du wheel. Vérifiez que expensekit/__init__.py et expensekit/cli.py sont présents. Évitez qu’une variable PYTHONPATH pointant vers vos sources ou une ancienne installation masque les fichiers manquants.
La commande fait deux sortes de contrôle : argparse refuse par exemple abc comme entier, tandis qu’un montant négatif déjà converti est refusé ensuite par total avec ValueError. Cet exemple minimal n’unifie pas encore tous les messages d’erreur. Testez ces chemins sur la version installée, ainsi que zéro, une liste vide pour la fonction et l’absence d’arguments pour la commande.
Les dépendances nécessaires au fonctionnement d’un paquet doivent être déclarées dans project.dependencies si elles existent ; cet exercice n’en ajoute pas. Les outils de développement et de construction ne sont pas automatiquement des dépendances d’exécution. La condition requires-python décrit votre engagement de compatibilité et doit correspondre aux versions réellement vérifiées.
Le projet présenté est volontairement minimal. Un outil de construction peut signaler l’absence de README sans que cela prouve une installation défectueuse. Une distribution destinée à d’autres personnes demande une documentation, une licence, des informations d’auteur exactes, une vérification des fichiers inclus et des secrets, ainsi qu’une politique de versions. Une publication sur PyPI exige aussi la vérification du nom et l’authentification du dépôt ; elle constitue une opération distincte du test local.
Après construction, les fichiers essentiels de l’exercice se présentent ainsi ; les outils peuvent ajouter d’autres fichiers de travail à côté :
project/
pyproject.toml
src/
expensekit/
__init__.py
cli.py
dist/
expensekit_demo-0.1.0-py3-none-any.whl
expensekit_demo-0.1.0.tar.gz
Conservez les sources dans le projet et les environnements comme des environnements recréables, pas comme des fichiers à inclure dans la distribution. La vérification décisive est le fonctionnement du wheel installé hors du dossier source, avec la fonction, le module CLI et la commande déclarée donnant les résultats attendus.




