create - Ejecute una instalación posterior de script de Python con distutils/setuptools
python setuptools setup (2)
Creo que la forma más fácil de realizar la instalación posterior y mantener los requisitos es decorar la llamada para 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=[''...
)
)
Esto ejecutará setup() al declarar la setup . Una vez hecho esto con la instalación de los requisitos, ejecutará la función _post_install() , que ejecutará la función interna _post_actions() .
Estoy tratando de agregar una tarea posterior a la instalación a distutils de Python, como se describe en Cómo extender distutils con un simple script de instalación posterior. . Se supone que la tarea ejecuta una secuencia de comandos de Python en el directorio lib instalado . Este script genera módulos de Python adicionales que requiere el paquete instalado.
Mi primer intento es el siguiente:
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},
)
Este enfoque funciona, pero hasta donde puedo decir tiene dos deficiencias:
- Si el usuario ha utilizado un intérprete de Python que no sea el recogido de
PATH, el script de post instalación se ejecutará con un intérprete diferente que podría causar un problema. - No es seguro contra el funcionamiento en seco, etc., que podría remediar envolviéndolo en una función y llamándolo con
distutils.cmd.Command.execute.
¿Cómo podría mejorar mi solución? ¿Hay alguna forma recomendada / mejor práctica para hacer esto? Me gustaría evitar establecer otra dependencia si es posible.
La forma de abordar estas deficiencias es:
- Obtenga la ruta completa al intérprete de Python que ejecuta
setup.pydesdesys.executable. Las clases que heredan de
distutils.cmd.Command(comodistutils.command.install.installydistutils.command.install.installque usamos aquí) implementan el método deexecute, que ejecuta una función determinada de una "manera segura", es decir, respetando el indicador de ejecución en seco.Sin embargo,
--dry-runcuenta que la opción--dry-runestá actualmente rota y no funciona de la manera prevista.
Terminé con la siguiente solución:
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},
)
Tenga en cuenta que utilizo la install nombre de clase para mi clase derivada porque eso es lo que python setup.py --help-commands .