2013-07-23 8 views
27

Próbuję dodać zadanie po instalacji do distutils Python, jak opisano w artykule How to extend distutils with a simple post install script?. Zadanie ma wykonać skrypt Python w zainstalowanym katalogu lib. Ten skrypt generuje dodatkowe moduły Pythona wymagane przez zainstalowany pakiet.Wykonywanie instalacji po zainstalowaniu skryptu w języku Python przy użyciu narzędzia distutils/setuptools

Moja pierwsza próba jest następujący:

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

Podejście to działa, ale o ile mogę powiedzieć, ma dwa braki:

  1. Jeśli użytkownik korzystał interpreter Pythona inne niż jeden podniósł z PATH, skrypt po instalacji zostanie wykonany z inny interpretator, który może powodować problem.
  2. Nie jest bezpieczny przed pracą na sucho itp., Co mógłbym rozwiązać, zawijając ją w funkcję i wywołując ją pod numerem distutils.cmd.Command.execute.

Jak mogę poprawić swoje rozwiązanie? Czy istnieje zalecany sposób/najlepsza praktyka w tym zakresie? Chciałbym uniknąć, jeśli to możliwe, innej zależności.

+0

Dla tych, którzy chcą mieć możliwość używania także 'python setup.py install', a także' pip install', zobacz: http://stackoverflow.com/questions/21915469/python-setuptools-install-requires -is-ignored-when-overriding-cmdclass –

Odpowiedz

34

Sposobem na rozwiązanie tych niedostatków jest:

  1. uzyskać pełną ścieżkę do interpretera Pythona wykonującego setup.py od sys.executable.
  2. Klasy dziedziczące od distutils.cmd.Command (takie jak distutils.command.install.install, których używamy tutaj) realizują metodę execute, która wykonuje daną funkcję w "bezpieczny sposób", tj. Z zachowaniem flagi suchobiegu.

    Należy jednak pamiętać, że the --dry-run option is currently broken i nie działa tak jak należy.

skończyło się następujące rozwiązanie:

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

pamiętać, że używanie nazwy klasy install dla mojej klasie pochodnej, ponieważ to właśnie python setup.py --help-commands użyje.

+0

dziękuję, to naprawdę pomogło, musiałem także podążać (http://stackoverflow.com/questions/15853058/run-custom-task-when-call-pip-install) aby uniknąć błędu w mojej instalacji pip. Połączyłem to wszystko w blogu (http://diffbrent.ghost.io/correctly-adding-nltk-to-your-python-package-using-setup-py-post-install-commands/). Daj mi znać, jeśli coś przeoczyłem. –

+0

@ brent.payne Cieszę się, że pomogło! Zauważ mój komentarz, dlaczego użyłem 'install' jako nazwy klasy. – kynan

+1

działa, ale nie udało mi się przeprowadzić instalacji niestandardowej za pomocą 'pip install -e name'. ps, właśnie znalazłem [ten link] (http://www.niteoweb.com/blog/setuptools-run-custom-code-during-install), zobacz sekcję BONUS. – Paolo

Powiązane problemy