Ich versuche, eine Python-Distutils-Aufgabe nach der Installation hinzuzufügen, wie in So erweitern Sie Distutils mit einem einfachen Post-Installationsskript? Beschrieben. Die Task soll ein Python-Skript im installierten lib-Verzeichnis ausführen. Dieses Skript generiert zusätzliche Python-Module, die für das installierte Paket erforderlich sind.
Mein erster Versuch ist wie folgt:
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},
)
Dieser Ansatz funktioniert, aber soweit ich das beurteilen kann, hat er zwei Mängel:
PATH
verwendeten verwendet hat, wird das Skript nach der Installation mit einem different - Interpreter ausgeführt, was zu Problemen führen kann.distutils.cmd.Command.execute
aufrufe.Wie kann ich meine Lösung verbessern? Gibt es dafür einen empfohlenen Weg/eine bewährte Methode? Ich möchte vermeiden, wenn möglich, eine andere Abhängigkeit einzuziehen.
Der Umgang mit diesen Mängeln ist:
setup.py
von sys.executable
ausführt.Klassen, die von distutils.cmd.Command
erben (wie beispielsweise distutils.command.install.install
, die wir hier verwenden), implementieren die execute
-Methode, die eine gegebene Funktion auf "sichere Weise" ausführt, d. H. Unter Beachtung des Trockenlauf-Flags.
Beachten Sie jedoch, dass die --dry-run
-Option derzeit defekt ist und nicht wie beabsichtigt funktioniert.
Ich habe die folgende Lösung gefunden:
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},
)
Beachten Sie, dass ich für meine abgeleitete Klasse den Klassennamen install
benutze, da dies python setup.py --help-commands
verwendet.
Ich denke, der einfachste Weg, die Nachinstallation durchzuführen und die Anforderungen einzuhalten, besteht darin, den Aufruf an setup(...)
zu dekorieren:
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=['...
)
)
Dies wird setup()
ausgeführt, wenn setup
deklariert wird. Sobald die Installation der Anforderungen abgeschlossen ist, wird die Funktion _post_install()
ausgeführt, die die innere Funktion _post_actions()
ausführt.