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.py
desdesys.executable
. Las clases que heredan de
distutils.cmd.Command
(comodistutils.command.install.install
ydistutils.command.install.install
que 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-run
cuenta que la opción--dry-run
está 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
.