msi - windows python setuptools




Script post-installazione con setuptools Python (4)

È possibile specificare un file di script Python post-installazione come parte del file setuptools setup.py in modo che un utente possa eseguire il comando:

python setup.py install

su un archivio di file di progetto locale, o

pip install <name>

per un progetto PyPI e lo script verrà eseguito al termine dell'installazione standard setuptools? Sto cercando di eseguire attività di post-installazione che possono essere codificate in un singolo file di script Python (ad esempio, fornire un messaggio post-installazione personalizzato all'utente, estrarre file di dati aggiuntivi da un altro repository di sorgenti remote).

Mi sono imbattuto in questa risposta SO di diversi anni fa che affronta l'argomento e sembra che in quel momento il consenso fosse che è necessario creare un sottocomando install. Se questo è ancora il caso, sarebbe possibile che qualcuno fornisca un esempio su come farlo in modo che non sia necessario che l'utente inserisca un secondo comando per eseguire lo script?


Combinando le risposte di @Apalala, @Zulu e @mertyildiran; questo ha funzionato per me in un ambiente Python 3.5:

import atexit
import os
import sys
from setuptools import setup
from setuptools.command.install import install

class CustomInstall(install):
    def run(self):
        def _post_install():
            def find_module_path():
                for p in sys.path:
                    if os.path.isdir(p) and my_name in os.listdir(p):
                        return os.path.join(p, my_name)
            install_path = find_module_path()

            # Add your post install code here

        atexit.register(_post_install)
        install.run(self)

setup(
    cmdclass={'install': CustomInstall},
...

Questo ti dà anche accesso al percorso di installazione del pacchetto in install_path , per fare un po 'di lavoro sulla shell.


Penso che il modo più semplice per eseguire l'installazione successiva e mantenere i requisiti sia quello di decorare la chiamata 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=['...
    )
)

Ciò eseguirà setup() quando si dichiara l' setup . Una volta completata l'installazione dei requisiti, verrà eseguita la funzione _post_install() , che eseguirà la funzione interna _post_actions() .


Questa soluzione è più trasparente:

Otterrai alcune aggiunte a setup.py e non è necessario un file aggiuntivo.

Inoltre è necessario considerare due diverse post-installazioni; uno per la modalità di sviluppo / modificabile e l'altro per la modalità di installazione.

Aggiungi queste due classi che includono lo script di post-installazione a setup.py :

from setuptools import setup
from setuptools.command.develop import develop
from setuptools.command.install import install


class PostDevelopCommand(develop):
    """Post-installation for development mode."""
    def run(self):
        # PUT YOUR POST-INSTALL SCRIPT HERE or CALL A FUNCTION
        develop.run(self)

class PostInstallCommand(install):
    """Post-installation for installation mode."""
    def run(self):
        # PUT YOUR POST-INSTALL SCRIPT HERE or CALL A FUNCTION
        install.run(self)

e inserisci cmdclass argomento cmdclass nella funzione setup() in setup.py :

setup(
    ...

    cmdclass={
        'develop': PostDevelopCommand,
        'install': PostInstallCommand,
    },

    ...
)

È anche possibile chiamare i comandi della shell durante la post-installazione, in questo modo:

from setuptools import setup
from setuptools.command.develop import develop
from setuptools.command.install import install
from subprocess import check_call


class PostDevelopCommand(develop):
    """Post-installation for development mode."""
    def run(self):
        check_call("apt-get install this-package".split())
        develop.run(self)

class PostInstallCommand(install):
    """Post-installation for installation mode."""
    def run(self):
        check_call("apt-get install this-package".split())
        install.run(self)


setup(
    ...

PS non ci sono punti di ingresso pre-installazione disponibili su setuptools. Leggi questa discussione se ti stai chiedendo perché non ce n'è.


Se si utilizza atexit, non è necessario creare una nuova cmdclass. Puoi semplicemente creare il tuo registro atexit subito prima della chiamata a setup (). Fa la stessa cosa.

Inoltre, se è necessario installare prima le dipendenze, questo non funziona con l'installazione dei pip dal momento in cui il gestore di atexit verrà chiamato prima che pip sposti i pacchetti in posizione.





pypi