2013-07-23 15 views
27

Sto tentando di aggiungere un'attività di post-installazione alle distutils Python come descritto in How to extend distutils with a simple post install script?. Si suppone che l'attività esegua uno script Python nella directory lib installata. Questo script genera ulteriori moduli Python necessari per il pacchetto installato.Eseguire un'installazione post script Python utilizzando distutils/setuptools

Il mio primo tentativo è il seguente:

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}, 
) 

Questo approccio funziona, ma per quanto ne so ha due carenze:

  1. Se l'utente ha usato un interprete Python diverso da quello uno prelevato da PATH, lo script di postinstallazione verrà eseguito con un diverso interprete che potrebbe causare un problema.
  2. Non è sicuro contro il funzionamento a secco, ecc., Che potrei essere in grado di rimediare avvolgendolo in una funzione e chiamandolo con distutils.cmd.Command.execute.

Come posso migliorare la mia soluzione? Esiste un modo consigliato/le migliori pratiche per farlo? Mi piacerebbe evitare di tirare fuori un'altra dipendenza se possibile.

+0

Per coloro che vogliono essere in grado di utilizzare anche 'python setup.py install', nonché' pip install', consultare: http://stackoverflow.com/questions/21915469/python-setuptools-install-requires -è-ignorato-quando-sovrascrive-cmdclass –

risposta

34

Il modo per affrontare queste carenze è:

  1. ottenere il percorso completo per l'interprete Python esecuzione setup.py da sys.executable.
  2. Classi che ereditano da distutils.cmd.Command (come ad esempio distutils.command.install.install che usiamo qui) implementano il metodo execute, che esegue una determinata funzione in un "modo sicuro", cioè rispettando il flag di funzionamento a secco.

    Nota tuttavia che the --dry-run option is currently broken e non funziona come previsto in ogni caso.

ho finito con la seguente soluzione:

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}, 
) 

Nota che io uso il nome della classe install per la mia classe derivata, perché questo è ciò che useranno python setup.py --help-commands.

+0

grazie, questo davvero aiutato, ho anche bisogno di seguire (http://stackoverflow.com/questions/15853058/run-custom-task-when-call-pip-install) per evitare un errore nell'installazione del mio pip. Ho messo tutto insieme in un post sul blog (http://diffbrent.ghost.io/correctly-adding-nltk-to-your-python-package-using-setup-py-post-install-commands/). Fammi sapere se mi sono perso qualcosa. –

+0

@ brent.payne Felice di sentirlo aiutato! Nota il mio commento sul motivo per cui ho usato 'install' come nome di classe. – kynan

+1

funziona, ma non sono stato in grado di avere l'installazione personalizzata eseguita con 'pip install -e name'. ps, appena trovato [questo link] (http://www.niteoweb.com/blog/setuptools-run-custom-code-during-install), vedi la sezione BONUS. – Paolo

Problemi correlati