2009-10-07 12 views
21

Eine Sache, die ich hasse über distutils (ich denke, he is the evil who does this) ist, dass es die Shebang-Linie ändert. Mit anderen Worten, beschloß der rationelle und umwelt Vars SchriftBerühren Sie nicht meine Shebang

#!/usr/bin/env python 

in magisch umgewandelt wird

#!/whatever/absolute/path/is/my/python 

Dies auch mit grok zu sehen ist: Ich grokproject in einem virtualenv verwenden mein Projekt zu starten, aber Jetzt kann ich das Entwicklungsverzeichnis nicht mehr verschieben, da es absolute Pfade in die Shebang-Direktive einfügt.

Der Grund, warum ich frage die

  • ist ein doppelt ich es bewegen will, weil ich die Entwicklung in einem Verzeichnis (Versuchen) gestartet und jetzt will ich es in einen richtigen Weg zu bewegen, aber ich konnte nicht TU es. Also habe ich ein neues virtualenv und grokproject erstellt und meine Dateien kopiert. Das behebt das Problem, lässt aber meine Neugier auf eine rationellere Lösung unbefriedigt. Insbesondere, wenn der Verweis auf den Python-Interpreter virtualenv relativ wäre, wäre das Problem gar nicht erst aufgetreten. Sie kennen das Layout des Virtualenv, und Sie können leicht auf den Virtualenv Python verweisen.
  • Der zweite Grund ist, dass ich gerne in der Lage wäre, den virtualenv auf einen anderen Computer zu scannen und ihn dort ohne Probleme laufen zu lassen. Dies ist nicht möglich, wenn Sie über fest codierte Pfade verfügen.
+3

@Lennart hinzufügen: Weil ich ziemlich ärgerlich, dass alle meine Sachen installiert eine sehr starke und schmerzhafte Abhängigkeit gegen einen bestimmten Pfad hat meines Dateisystems, insbesondere wenn eine Alternative existiert. –

+0

Sie wollen es also verschieben, nur weil es nicht offensichtlich ist, wie? :-) Oooookay ... –

+0

@Lennart: zu der Frage hinzugefügt. –

Antwort

13

Natürlich können Sie das Entwicklungsverzeichnis verschieben. Distutils ändert die Pfade zu dem Python, mit dem Sie es ausführen sollten, wenn Sie es ausführen. Es ist in Grok run, wenn Sie das Buildout ausführen. Verschieben Sie den Bootstrap und das Buildout und führen Sie ihn erneut aus. Erledigt!

Distutils ändert den Pfad zu dem Python, mit dem Sie distutils ausführen. Wenn dies nicht der Fall ist, kann es passieren, dass Sie eine Bibliothek in einer Python-Version installieren. Wenn Sie jedoch versuchen, das Skript auszuführen, wird es fehlschlagen, da es mit einer anderen Python-Version ausgeführt werden würde, die nicht über die Bibliothek verfügt.

Das ist nicht Wahnsinn, es ist in der Tat der einzige vernünftige Weg, es zu tun.

Update: Wenn Sie wissen, was Sie tun, Sie können dies tun:

/path/to/install/python setup.py build -e "/the/path/you/want/python" install 

Stellen Sie sicher, das Build-Verzeichnis reinigen obwohl zuerst. :)

+0

Sie haben einen Punkt. Ich denke jedoch, dass es die Möglichkeit geben sollte, diese Transformation zu überspringen, wenn Sie das wirklich wollen. –

+1

Es kann, wenn Sie es als Datendateien anstatt als Skript installieren. Aber das wird sich brechen, sobald Sie es auf einem System installieren, das nicht genau wie Ihres aussieht. –

2

Ich habe keine Lösung für Ihr Problem, aber ich habe einige Gründe für das aktuelle Verhalten von distutils sehen.

#!/usr/bin/env python führt die Standard-Python-Version des Systems aus. Das ist in Ordnung, solange Ihr Code mit dieser Version kompatibel ist. Wenn die Standardversion aktualisiert wird (z. B. von 2.5 auf 3), funktioniert Ihr Code oder anderer Python-Code, der auf /usr/bin/env verweist, möglicherweise nicht mehr, obwohl die alte Python-Version noch installiert ist. Aus diesem Grund ist es sinnvoll, den Pfad zum entsprechenden Python-Interpreter "fest zu codieren".

Bearbeiten: Sie sind richtig in der Geltendmachung, dass die Angabe python2.4 oder ähnliches dieses Problem löst.

Edit 2: Dinge sind nicht so klar, wenn mehrere Installationen der gleichen Python-Version vorhanden sind, wie Ned Deily in den Kommentaren unten zeigt.

+0

können Sie python24 verwenden. Tatsache ist, dass Sie, wenn Sie ein virtualenv haben, möchten, dass Sie es bewegen können, wenn Sie das entscheiden. Ein relativer Pfad wäre besser, da beim Erstellen des Virtualenv alles in diesem Verzeichnis enthalten ist und alles relativ bezeichnet werden kann. –

+0

Ich habe keine Erfahrung mit Distutils. Ihre Frage zitiert '#!/Usr/bin/env python' anstelle von' #!/Usr/bin/env python2.4'. Welche davon haben Sie in Ihrem Code angegeben? Führt distutils auch das Neuschreiben durch, wenn die Versionsnummer angegeben ist? – Stephan202

+0

Auf einigen Systemen ist es nicht ungewöhnlich, dass mehr als eine Instanz der * gleichen * Version von Python installiert ist. auf diesem System habe ich 3 Versionen von Python2.5 und das zählt nicht virtualenvs. Wie Lennart betont, werden Skripte in einer bestimmten Interpreterinstallation installiert und an diese gebunden. Aus diesem Grund garantieren relative Shebang-Pfade im allgemeinsten Fall kein korrektes Verhalten. –

8

Distutils wird den Shebang automatisch durch den Speicherort der Python-Binärdatei ersetzen, die zum Ausführen von setup.py verwendet wurde. Um dieses Verhalten zu überschreiben, haben Sie zwei Möglichkeiten:

Option 1: Manuelles

Sie können die Flagge passieren --executable =/path/to/my/python setup.py. Argumente werden akzeptiert.

Beispiel:

% python setup.py build --executable=/opt/local/bin/python -d 

Option 2: Automatisch

Ihre andere Möglichkeit ist es, eine Zeile hinzufügen setup.cfg. Wenn Sie setup.cfg nicht verwenden, erstellen Sie es im selben Verzeichnis wie setup.py. Setup.py sucht dies beim Start. Alle hier angegebenen Optionen können weiterhin mit Flags in der Befehlszeile überschrieben werden.

% cat setup.cfg 
[build] 
executable = /opt/local/bin/python -d 
+0

Danke dafür. Das ist fantastisch. Ich kann das nirgendwo dokumentiert finden. Möchten Sie einige Dokumentationslinks veröffentlichen? –

+0

'python setup.py build --help';) – jathanism

+0

Gibt es etwas ähnliches für' python setup.py develop'? Mein virtualenv-Setup führt zu einigen sehr langen Shebang-Pfaden, die beim Versuch, sie auszuführen, "schlechte Interpreter" -Fehler verursachen. Ich habe 'sys.executable = '/ usr/bin/env python'' aus dem Skript heraus versucht, aber der Platz scheint zu verursachen, dass Zitate in den Shebang geschrieben werden, was die Dinge auf andere Weise bricht. –

1

In einem der neuesten Versionen von distutils, ist ein Flag gibt --no-autoreq die für mich gearbeitet haben:

--no-autoreq   do not automatically calculate dependencies 

In meinem Fall wurde ich RPM Erstellung Dateien mit ausführbarer Python2.4-Datei auf einem Server mit 2.4- und 2.6-Installationen. bdist links nur die Bauden, wie sie waren, nach dem Laufen:

python setup.py bdist_rpm --no-autoreq 

Im Fall, dass Sie den Umgang mit den spec Dateien, können Sie die Lösung bei https://stackoverflow.com/a/7423994/722997 erklärt verwenden, und fügte hinzu:

AutoReq: no 
1

hatte das gleiche Problem. versuchte einen Weg zu finden, die Berührungen standardmäßig zu verhindern. Hier ist die Lösung. Im Wesentlichen überschreiben wir die Standardroutine zum Kopieren von Skripten (build_scripts).

in setup.py

from distutils.command.build_scripts import build_scripts 

# don't touch my shebang 
class BSCommand (build_scripts): 
    def run(self): 
     """ 
     Copy, chmod each script listed in 'self.scripts' 
     essentially this is the stripped 
     distutils.command.build_scripts.copy_scripts() 
     routine 
     """ 
     from stat import ST_MODE 
     from distutils.dep_util import newer 
     from distutils import log 

     self.mkpath(self.build_dir) 
     outfiles = [] 
     for script in self.scripts: 
      outfile = os.path.join(self.build_dir, os.path.basename(script)) 
      outfiles.append(outfile) 

      if not self.force and not newer(script, outfile): 
       log.debug("not copying %s (up-to-date)", script) 
       continue 

      log.info("copying and NOT adjusting %s -> %s", script, 
         self.build_dir) 
      self.copy_file(script, outfile) 

     if os.name == 'posix': 
      for file in outfiles: 
       if self.dry_run: 
        log.info("changing mode of %s", file) 
       else: 
        oldmode = os.stat(file)[ST_MODE] & 0o7777 
        newmode = (oldmode | 0o555) & 0o7777 
        if newmode != oldmode: 
         log.info("changing mode of %s from %o to %o", 
           file, oldmode, newmode) 
         os.chmod(file, newmode) 

setup(name="name", 
     version=version_string, 
     description="desc", 
     ... 
     test_suite='testing', 
     cmdclass={'build_scripts': BSCommand}, 
    ) 

.. ede/duply.net

Verwandte Themen