Auf Python 3.5.1, aber nicht auf 2.7.10, wenn ich pip durch einen Unterprozess in einer virtualenv aufrufe, werden die Skripte mit dem falschen Shebang erstellt und können daher nicht ausgeführt werden:
$ cat > invoke.py
import sys
import subprocess
subprocess.Popen(sys.argv[1:]).wait()
$ rm -Rf env
$ python -m virtualenv --version
14.0.0
$ python --version
Python 3.5.1
$ python -m virtualenv env
Using base prefix '/Library/Frameworks/Python.framework/Versions/3.5'
New python executable in /Users/jaraco/Dropbox/code/public/aspen/env/bin/python3
Also creating executable in /Users/jaraco/Dropbox/code/public/aspen/env/bin/python
Installing setuptools, pip, wheel...done.
$ python invoke.py env/bin/pip install pytest
Collecting pytest
Using cached pytest-2.8.5-py2.py3-none-any.whl
Collecting py>=1.4.29 (from pytest)
Using cached py-1.4.31-py2.py3-none-any.whl
Installing collected packages: py, pytest
Successfully installed py-1.4.31 pytest-2.8.5
$ head -n 1 env/bin/py.test
#!/Library/Frameworks/Python.framework/Versions/3.5/bin/python3
Man würde erwarten, dass das Skript py.test einen Shebang mit 'env' enthält.
Die Verwendung von pyvenv stattdessen ist nicht Gegenstand des Problems. Das Entfernen der Umgebungsvariablen __PYVENV_LAUNCHER__
vor dem Starten des Unterprozesses umgeht das Problem, wie hier gemeldet . Das Problem wurde mit 13.1.2 und 14.0.0 beobachtet.
Ist dieses Verhalten zu erwarten? Wenn ja, ist das Entfernen der Umgebungsvariablen für einen übergeordneten Prozess angemessen, um das Problem zu umgehen?
tut
$ env/bin/pip uninstall pytest
$ env/bin/pip install pytest
$ head -n 1 env/bin/py.test
Gleiche oder unterschiedliche Ergebnisse liefern?
Und gleiche Frage mit
$ env/bin/python -m pip install pytest
?
Möglicherweise eine Regression irgendwie auf https://github.com/pypa/virtualenv/issues/322 / https://github.com/pypa/virtualenv/pull/541
Können Sie in diesem Fall testen, ob
subprocess.Popen(sys.argv[1:], env={}).wait()
hilft oder nicht?
Hmm, es gab Code in pip / distlib, um vielleicht damit umzugehen, aber er wurde vor einem Jahr auskommentiert-
Gleiche oder unterschiedliche Ergebnisse liefern?
In beiden Fällen führt das Aufrufen von pip direkt zu einem richtigen Shebang:
$ env/bin/pip install pytest
Collecting pytest
Using cached pytest-2.8.5-py2.py3-none-any.whl
Requirement already satisfied (use --upgrade to upgrade): py>=1.4.29 in ./env/lib/python3.5/site-packages (from pytest)
Installing collected packages: pytest
Successfully installed pytest-2.8.5
$ head -n 1 env/bin/py.test
#!/Users/jaraco/Dropbox/code/public/aspen/env/bin/python3
$ env/bin/pip uninstall -y pytest
Uninstalling pytest-2.8.5:
Successfully uninstalled pytest-2.8.5
$ env/bin/python -m pip install pytest
Collecting pytest
Using cached pytest-2.8.5-py2.py3-none-any.whl
Requirement already satisfied (use --upgrade to upgrade): py>=1.4.29 in ./env/lib/python3.5/site-packages (from pytest)
Installing collected packages: pytest
Successfully installed pytest-2.8.5
$ head -n 1 env/bin/py.test
#!/Users/jaraco/Dropbox/code/public/aspen/env/bin/python
Auch das Aufrufen mit einer leeren env funktioniert:
$ cat invoke.py
import sys
import os
import subprocess
env = dict(os.environ)
env.pop('__PYVENV_LAUNCHER__')
env = {}
subprocess.Popen(sys.argv[1:], env=env).wait()
$ python -m virtualenv env
Using base prefix '/Library/Frameworks/Python.framework/Versions/3.5'
New python executable in /Users/jaraco/Dropbox/code/public/aspen/env/bin/python3
Also creating executable in /Users/jaraco/Dropbox/code/public/aspen/env/bin/python
Installing setuptools, pip, wheel...done.
$ python invoke.py env/bin/pip install pytest
Collecting pytest
Using cached pytest-2.8.5-py2.py3-none-any.whl
Collecting py>=1.4.29 (from pytest)
Using cached py-1.4.31-py2.py3-none-any.whl
Installing collected packages: py, pytest
Successfully installed py-1.4.31 pytest-2.8.5
$ head -n 1 env/bin/py.test
#!/Users/jaraco/Dropbox/code/public/aspen/env/bin/python3
Laut Commit wurde diese Problemumgehung mit der Aufnahme von distlib 0.2.0 in pip 6.0 kommentiert.
Dieser Commit verweist auf pip 2031 .
Außerdem habe ich Python über das python.org Mac-Installationsprogramm installiert, nicht über Homebrew oder andere Methoden.
Der Code wurde in diesem Commit aus distlib entfernt , was wenig
Ich denke, es ist "zu erwarten", da Ihr anfängliches $ python
__VENV_LAUNCHER__
festlegt und danach andere Skripte / ausführbare Dateien täuscht. Leider habe ich kein OS X, um zu debuggen, wie genau dieser Prozess des "Täuschens" abläuft.
Könnte auch ein ähnliches / gleiches Problem sein, wie in #620 gemeldet wurde
@jaraco es könnte sich lohnen, ein pip
in einem virtualenv zu modifizieren, um die erwähnten Distlib-Zeilen zu entkommentieren und zu sehen, ob dies das Verhalten von pip zu beheben scheint, das falsche Python zum Schreiben aufzunehmen
Ich habe diesen venv-Erkennungscode bis zu diesem Commit zurückverfolgt, was leider die Ursprünge der Idee nicht aufklärt.
Scheint, dass niemand die Bedeutung dieser env var kennt .
Ich habe diese Erklärung gefunden .
Meine Neigung war ähnlich der, die Ronald hier vorgeschlagen hat .
@vsajip könntest du einen Rat geben?
Einige Gedanken:
__PYVENV_LAUNCHER__
wurde hinzugefügt, weil für frühere Versionen von Python (< 3.3, laut Ronald), aber nicht für spätere Versionen, Pythons site.py
unter OS X benötigte, um die Position von Stub-Startprogrammen von ausführbaren Framework-Dateien zu unterscheiden. Laut diesem Kommentar von Ned Deily zeigt sys.executable
jetzt auf den Stub-Launcher, und deshalb hat distlib
aufgehört, __PYVENV_LAUNCHER__
. Die einzige Verwendung davon ist jetzt in site.py
- falls verfügbar, wird es unter OS X verwendet, um die Datei pyvenv.cfg
.os.path.realpath()
Anruf tätigt, obwohl dies nicht der Fall sein sollte. Es sieht nicht so aus, als ob es distlib
tun würde. Wenn (gemäß Neds Kommentar) sys.executable
und die env var immer gleich sind, dann sollte es keine Rolle spielen; aber wenn etwas realpath
auf einem sys.executable
ausführt und Python durch das Ergebnis ausführt, dann würde das zu einem unerwarteten Shebang führen (weil sys.executable
dann ein dereferenzierter Pfad wäre).Eine (weitere) einfache Demonstration des Problems, das Homebrew in https://github.com/Homebrew/homebrew-core/pull/8129 wiederentdeckt hat:
$ virtualenv -p python3 test
$ test/bin/python3 -c 'import sys; print(sys.executable)'
/Users/tim/test/bin/python3
$ /usr/local/bin/python3 -c 'import subprocess; subprocess.call(["/Users/tim/test/bin/python3", "-c", "import sys; print(sys.executable)"])'
/usr/local/bin/python3
$ /usr/local/bin/python3 -c 'import subprocess, os; del os.environ["__PYVENV_LAUNCHER__"]; subprocess.call(["/Users/tim/test/bin/python3", "-c", "import sys; print(sys.executable)"])'
/Users/tim/test/bin/python3
Ich wurde gerade von genau diesem Fehler gebissen. Es ist meiner Meinung nach ein ziemlich schwerwiegender Fehler, vor allem, weil er so extrem verwirrend und schwer zu erkennen ist, wenn er trifft.
Ich wurde von einer meiner Meinung nach schwerwiegenderen Manifestation dieses Problems getroffen.
Ich habe angefangen, xonsh als meine tägliche Shell zu verwenden.
Aber wenn ich versuche, virtualenv unter xonsh zu verwenden, ist es unbrauchbar:
~ $ cd ~/draft
draft $ virtualenv --version
16.0.0
draft $ virtualenv .env
Using base prefix '/Library/Frameworks/Python.framework/Versions/3.7'
New python executable in /Users/jaraco/draft/.env/bin/python3
Also creating executable in /Users/jaraco/draft/.env/bin/python
Installing setuptools, pip, wheel...done.
draft $ .env/bin/pip install paver
Collecting paver
Using cached https://files.pythonhosted.org/packages/98/1e/37ba8a75bd77ea56a75ef5ae66fe657b79205bbc36556c9456cd641782a4/Paver-1.3.4-py2.py3-none-any.whl
Collecting six (from paver)
Using cached https://files.pythonhosted.org/packages/67/4b/141a581104b1f6397bfa78ac9d43d8ad29a7ca43ea90a2d863fe3056e86a/six-1.11.0-py2.py3-none-any.whl
Installing collected packages: six, paver
Successfully installed paver-1.3.4 six-1.11.0
The script paver is installed in '/Users/jaraco/draft/.env/bin' which is not on PATH.
Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
draft $ .env/bin/paver --help
Traceback (most recent call last):
File ".env/bin/paver", line 7, in <module>
from paver.tasks import main
ModuleNotFoundError: No module named 'paver'
draft $ head -n 1 .env/bin/paver
#!/Library/Frameworks/Python.framework/Versions/3.7/bin/python3
Alle installierten Skripte scheinen das Systempräfix und nicht das virtualenv-Präfix zu erhalten.
Dies liegt wahrscheinlich daran, dass xonsh unter Python 3.7 (Systempräfix) läuft und dies auch in der Umgebung hat:
draft $ env | grep LAUNCHER
__PYVENV_LAUNCHER__=/Library/Frameworks/Python.framework/Versions/3.7/bin/python3
Wenn ich stattdessen zsh starte und dieselben Befehle ausführe oder zuerst del $__PYVENV_LAUNCHER__
aufrufe, läuft paver wie erwartet und die Shebang-Linie zeigt auf die virtualenv.
Sollte xonsh diese Umgebungsvariable beim Start löschen?
Es gibt einen möglichen Bugfix unter https://github.com/python/cpython/pull/9516
Dieses Problem wurde automatisch als veraltet markiert, da es in letzter Zeit keine Aktivität hatte. Es wird geschlossen, wenn keine weitere Aktivität stattfindet. Fügen Sie einfach einen Kommentar hinzu, wenn Sie ihn geöffnet lassen möchten. Vielen Dank für Ihre Beiträge.
Ich sehe dieses Verhalten immer noch bei Mojave mit Python 3.7.6 (installiert über Homebrew).
Kannst du mit dem Rewrite-Zweig nachschauen?
@gaborbernat Der Versuch, den rewrite
Zweig (fbdd782257d8eace7f5440a2b665f2ddb72e9db6) zu erstellen, gibt mir einen Build-Fehler von python3 setup.py build
.
...src/virtualenv/__init__.py", line 3, in <module>
from .version import __version__
ModuleNotFoundError: No module named 'virtualenv.version'
was anscheinend nichts mit diesem Problem zu tun hat.
Beim Versuch, den Rewrite-Zweig (fbdd782) zu erstellen, erhalte ich einen Build-Fehler von python3 setup.py build.
Sie sollten pip verwenden, um den Build durchzuführen - pip wheel .
- da der Rewrite-Zweig pyproject.toml
, um den Build-Prozess zu definieren.
Der Fehler, den Sie erhalten, ist, dass setuptools sagt, dass ich die neue Standardmethode zum Erstellen von Python-Bibliotheken (PEP-517/518) nicht unterstütze. Es ist bestenfalls ein Setuptools-Fehler, aber wie @pfmoore darauf hingewiesen hat, sollten Sie pip verwenden, um ein Rad zu bauen, oder noch besser, es auf den virtualenv-Ordner zu verweisen, um es zu installieren (es wird automatisch ein Rad erstellen und in einem Schritt installieren).
Testfall:
#!/bin/bash
rm -rf venv-test
virtualenv --python python3 venv-test
python3 -c 'import subprocess; subprocess.check_call(["./venv-test/bin/pip3", "install", "markdown"])'
shebang=$(head -1 venv-test/bin/markdown_py)
expected_shebang="#!$(pwd)/venv-test/bin/python"
if [ "$shebang" == "$expected_shebang" ]; then
echo "PASSED"
else
echo "FAILED: \"$shebang\" != \"$expected_shebang\""
exit 1
fi
Dies schlägt unter python3+virtualenv 16.7.9 fehl und geht unter python3+virtualenv-16.7.10.dev11+gfbdd782 (dh dem rewrite
Zweig) weiter.
Behoben im Rewrite wie oben beschrieben.
Hilfreichster Kommentar
Ich wurde gerade von genau diesem Fehler gebissen. Es ist meiner Meinung nach ein ziemlich schwerwiegender Fehler, vor allem, weil er so extrem verwirrend und schwer zu erkennen ist, wenn er trifft.