J'essaie d'ajouter une tâche de post-installation à Python distutils comme décrit dans Comment étendre distutils avec un simple script de post-installation? . La tâche est supposée exécuter un script Python dans le répertoire lib installé . Ce script génère des modules Python supplémentaires requis par le paquet installé.
Ma première tentative est la suivante:
from distutils.core import setup
from distutils.command.install import install
class post_install(install):
def run(self):
install.run(self)
from subprocess import call
call(['python', 'scriptname.py'],
cwd=self.install_lib + 'packagename')
setup(
...
cmdclass={'install': post_install},
)
Cette approche fonctionne, mais pour autant que je sache, elle présente deux inconvénients:
PATH
, le script de post-installation sera exécuté avec un interpréteur différent , ce qui pourrait poser problème.distutils.cmd.Command.execute
.Comment pourrais-je améliorer ma solution? Existe-t-il un moyen/une pratique recommandée pour ce faire? J'aimerais éviter de créer une autre dépendance si possible.
La façon de remédier à ces carences est la suivante:
setup.py
à partir de sys.executable
.Les classes héritées de distutils.cmd.Command
(comme distutils.command.install.install
que nous utilisons ici) implémentent la méthode execute
, qui exécute une fonction donnée de manière "sans danger", c'est-à-dire en respectant l'indicateur d'exécution à sec.
Notez cependant que l'option --dry-run
est actuellement cassée et ne fonctionne pas comme prévu de toute façon.
J'ai fini avec la solution suivante:
import os, sys
from distutils.core import setup
from distutils.command.install import install as _install
def _post_install(dir):
from subprocess import call
call([sys.executable, 'scriptname.py'],
cwd=os.path.join(dir, 'packagename'))
class install(_install):
def run(self):
_install.run(self)
self.execute(_post_install, (self.install_lib,),
msg="Running post install task")
setup(
...
cmdclass={'install': install},
)
Notez que j’utilise le nom de classe install
pour ma classe dérivée car c’est ce que python setup.py --help-commands
utilisera.
Je pense que le moyen le plus simple d'effectuer la post-installation et de respecter les exigences consiste à décorer l'appel à setup(...)
:
from setup tools import setup
def _post_install(setup):
def _post_actions():
do_things()
_post_actions()
return setup
setup = _post_install(
setup(
name='NAME',
install_requires=['...
)
)
Ceci fonctionnera setup()
lors de la déclaration de setup
. Une fois l’installation des exigences terminée, il lancera la fonction _post_install()
, qui exécutera la fonction interne _post_actions()
.