2.7.10์ด ์๋ Python 3.5.1์์ virtualenv์ ํ์ ํ๋ก์ธ์ค๋ฅผ ํตํด pip๋ฅผ ํธ์ถํ๋ฉด ์คํฌ๋ฆฝํธ๊ฐ ์๋ชป๋ shebang์ผ๋ก ์์ฑ๋์ด ์คํ์ ์คํจํฉ๋๋ค.
$ 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
py.test ์คํฌ๋ฆฝํธ์๋ 'env'๊ฐ ํฌํจ๋ shebang์ด ์์ ๊ฒ์ผ๋ก ์์๋ฉ๋๋ค.
๋์ pyvenv๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ๋ฌธ์ ์ ๋์์ด ์๋๋๋ค. ์ฌ๊ธฐ์ ๋ณด๊ณ ๋ ๋๋ก ํ์ ํ๋ก์ธ์ค๋ฅผ ์์ํ๊ธฐ ์ ์ __PYVENV_LAUNCHER__
ํ๊ฒฝ ๋ณ์๋ฅผ ์ ๊ฑฐํ๋ฉด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์์ต๋๋ค . ์ด ๋ฌธ์ ๋ 13.1.2 ๋ฐ 14.0.0์์ ๊ด์ฐฐ๋์์ต๋๋ค.
์ด ๋์์ด ์์๋ฉ๋๊น? ๊ทธ๋ ๋ค๋ฉด ํ๊ฒฝ ๋ณ์๋ฅผ ์ ๊ฑฐํ๋ ๊ฒ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ๋ถ๋ชจ ํ๋ก์ธ์ค๊ฐ ์ํํ๋ ์ ์ ํ ์์ ์ ๋๊น?
ํ๋ค
$ env/bin/pip uninstall pytest
$ env/bin/pip install pytest
$ head -n 1 env/bin/py.test
๋์ผํ ๊ฒฐ๊ณผ๋ฅผ ์ ๊ณตํฉ๋๊น, ์๋๋ฉด ๋ค๋ฅธ ๊ฒฐ๊ณผ๋ฅผ ์ ๊ณตํฉ๋๊น?
๊ทธ๋ฆฌ๊ณ ๊ฐ์ ์ง๋ฌธ
$ env/bin/python -m pip install pytest
?
https://github.com/pypa/virtualenv/issues/322 / https://github.com/pypa/virtualenv/pull/541 ์์ ํ๊ท ๊ฐ๋ฅ์ฑ์ด
์ด๋ค ๊ฒฝ์ฐ์ธ์ง ํ ์คํธ ํ ์ ์์ต๋๊น?
subprocess.Popen(sys.argv[1:], env={}).wait()
๋์์ด ๋๋ ๋ง๋ ?
ํ , pip / distlib์ ์ด๋ฅผ ์ฒ๋ฆฌํ๋ ์ฝ๋๊ฐ ์์์ง๋ง 1๋ ์ ์ ์ฃผ์ ์ฒ๋ฆฌ๋์์ต๋๋ค.
๋์ผํ ๊ฒฐ๊ณผ๋ฅผ ์ ๊ณตํฉ๋๊น, ์๋๋ฉด ๋ค๋ฅธ ๊ฒฐ๊ณผ๋ฅผ ์ ๊ณตํฉ๋๊น?
๋ ๊ฒฝ์ฐ ๋ชจ๋ pip๋ฅผ ์ง์ ํธ์ถํ๋ฉด ์ ์ ํ 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
๋ํ ๋น env๋ก ํธ์ถํ๋ฉด ๋ค์๊ณผ ๊ฐ์ด ์๋ํฉ๋๋ค.
$ 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
commit ์ ๋ฐ๋ฅด๋ฉด ํด๋น ํด๊ฒฐ ๋ฐฉ๋ฒ์ pip 6.0์์ ๋ฆด๋ฆฌ์ค๋ distlib 0.2.0์ ํฌํจํ๋ ๊ฒ์ผ๋ก ์ค๋ช ๋์์ต๋๋ค.
ํด๋น ์ปค๋ฐ์ pip 2031 ์ ์ฐธ์กฐํฉ๋๋ค.
๋ํ homebrew๋ ๋ค๋ฅธ ๋ฐฉ๋ฒ์ด ์๋ python.org Mac ์ค์น ํ๋ก๊ทธ๋จ์์ Python์ ์ค์นํ์ต๋๋ค.
์ด ์ปค๋ฐ์ distlib์์ ์ฝ๋๊ฐ
์ด๊ธฐ $ python
๊ฐ __VENV_LAUNCHER__
ํ๊ณ ๊ทธ ํ ๋ค๋ฅธ ์คํฌ๋ฆฝํธ/์คํ ํ์ผ์ ์์ด๊ณ ์๋ค๋ ์ ์ ๊ฐ์ํ ๋ "์์"๋ ๊ฒ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค. ๋ถํํ๋ ๋๋ "์์์"์ ํ๋ก์ธ์ค๊ฐ ์ ํํ ์ด๋ป๊ฒ ์งํ๋๋์ง ๋๋ฒ๊ทธํ OS X์ด ์์ต๋๋ค.
๋ํ #620์์ ๋ณด๊ณ ๋ ๊ฒ๊ณผ ์ ์ฌํ/๋์ผํ ๋ฌธ์ ์ผ ์ ์์ต๋๋ค.
@jaraco ๊ฐ์ ํ๊ฒฝ ์์ pip
๋ฅผ ์์ ํ์ฌ ์ธ๊ธ๋ distlib ํ์ ์ฃผ์ ์ฒ๋ฆฌ๋ฅผ ์ ๊ฑฐํ๊ณ ์์ฑํ ์๋ชป๋ ํ์ด์ฌ์ ์ ํํ๋ pip์ ๋์์ ์์ ํ๋ ๊ฒ์ผ๋ก ๋ณด์ด๋์ง ํ์ธํ๋ ๊ฒ์ด ๊ฐ์น๊ฐ ์์ ์ ์์ต๋๋ค.
๋๋ ๊ทธ venv ๊ฐ์ง ์ฝ๋๋ฅผ ์ด ์ปค๋ฐ์ผ๋ก ๋ค์ ์ถ์ ํ๋๋ฐ ๋ถํํ๋ ์์ด๋์ด์ ๊ธฐ์์ ์ค๋ช ํ์ง ๋ชปํ์ต๋๋ค.
์๋ฌด๋ ์ด env var ์ ์๋ฏธ๋ฅผ ๋ชจ๋ฅด๋ ๊ฒ ๊ฐ์ต๋๋ค.
์ด ์ค๋ช ์ ์ฐพ์์ต๋๋ค.
๋์ ์ฑํฅ์ Ronald๊ฐ ์ฌ๊ธฐ์์ ์ ์ํ ๊ฒ๊ณผ ์ ์ฌ
@vsajip ์กฐ์ธ์ ์ฃผ์ค ์ ์์ต๋๊น?
๋ช ๊ฐ์ง ์๊ฐ:
__PYVENV_LAUNCHER__
์ดํ ๋ฒ์ (๋ก๋๋์ ๋ฐ๋ฅด๋ฉด, <3.3) ๋๋ฌธ์ ํ์ด์ฌ ์ด์ ๋ฒ์ ์ ์ถ๊ฐ๊ฐ ์๋ ํ, ํ์ด์ฌ์ site.py
OS X ํ๋ ์ ์ํฌ ์คํ์์ ์คํ
๋ฐ์ฌ๋์ ์์น๋ฅผ ๊ตฌ๋ถํ๊ธฐ ์ํด ํ์์. Ned Deily์ ์ด ๋๊ธ ์ ๋ฐ๋ฅด๋ฉด sys.executable
์ด์ ์คํ
๋ฐ์ฒ๋ฅผ ๊ฐ๋ฆฌํค๋ฉฐ ์ด๊ฒ์ด distlib
๊ฐ __PYVENV_LAUNCHER__
์ฌ์ฉ์ ์ค๋จํ ์ด์ ์
๋๋ค. ์ง๊ธ์ site.py
์์๋ง ์ฌ์ฉ๋ฉ๋๋ค. ์ฌ์ฉ ๊ฐ๋ฅํ ๊ฒฝ์ฐ OS X์์๋ pyvenv.cfg
ํ์ผ์ ์ฐพ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.os.path.realpath()
ํธ์ถ์ ํด์๋ ์ ๋ ๋ ํ๊ณ ์๋ ๊ฒ ๊ฐ์ต๋๋ค. distlib
๊ทธ๋ ๊ฒ ํ๋ ๊ฒ ๊ฐ์ง ์์ต๋๋ค. (Ned์ ์๊ฒฌ์ ๋ฐ๋ผ) sys.executable
์ env var๊ฐ ํญ์ ๊ฐ์ผ๋ฉด ๋ฌธ์ ๊ฐ ๋์ง ์์ต๋๋ค. ๊ทธ๋ฌ๋ ๋ฌด์ธ๊ฐ๊ฐ realpath
์ ๋ํด sys.executable
๋ฅผ ์ํํ๊ณ ๊ฒฐ๊ณผ๋ฅผ ํตํด Python์ ์คํํ๋ฉด ์๊ธฐ์น ์์ ํ์๋ฆฌ๊ฐ ๋ฐ์ํฉ๋๋ค( sys.executable
๋ ์ญ์ฐธ์กฐ ๊ฒฝ๋ก์ด๊ธฐ ๋๋ฌธ์).Homebrew๊ฐ https://github.com/Homebrew/homebrew-core/pull/8129 ์์ ์ฌ๋ฐ๊ฒฌํ ๋ฌธ์ ์ ๋ํ ๊ฐ๋จํ ๋ฐ๋ชจ:
$ 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
๋๋์ด ์ ํํ ๋ฒ๊ทธ์ ๋ฌผ๋ ธ๋ค. ์ ์๊ฐ์๋ ๋งค์ฐ ์ฌ๊ฐํ ๋ฒ๊ทธ์ ๋๋ค. ๋๋ถ๋ถ์ด ๋งค์ฐ ํผ๋์ค๋ฝ๊ณ ์ธ์ ๋ฐ์ํ๋์ง ํ์ ํ๊ธฐ ์ด๋ ต๊ธฐ ๋๋ฌธ์ ๋๋ค.
๋๋ ์ด ๋ฌธ์ ์ ๋ ์ฌ๊ฐํ ์งํ๋ผ๊ณ ์๊ฐํ๋ ๊ฒ์ ํ๊ฒฉ์ ๋ฐ์์ต๋๋ค.
xonsh๋ฅผ ์ผ์์ ์ธ ์๋ก ์ฌ์ฉํ๊ธฐ ์์ํ์ต๋๋ค.
๊ทธ๋ฌ๋ xonsh์์ virtualenv๋ฅผ ์ฌ์ฉํ๋ ค๊ณ ํ๋ฉด ์ฌ์ฉํ ์ ์์ต๋๋ค.
~ $ 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
์ค์น๋ ๋ชจ๋ ์คํฌ๋ฆฝํธ๋ virtualenv ์ ๋์ฌ๊ฐ ์๋ ์์คํ ์ ๋์ฌ๋ฅผ ์ป๋ ๊ฒ ๊ฐ์ต๋๋ค.
์ด๊ฒ์ ์๋ง๋ xonsh๊ฐ Python 3.7(์์คํ ์ ๋์ฌ)์์ ์คํ ์ค์ด๊ณ env์ ๋ค์๊ณผ ๊ฐ์ด ์๋ค๋ ์ฌ์ค์์ ๋น๋กฏ๋ ๊ฒ ๊ฐ์ต๋๋ค.
draft $ env | grep LAUNCHER
__PYVENV_LAUNCHER__=/Library/Frameworks/Python.framework/Versions/3.7/bin/python3
๋์ zsh๋ฅผ ์์ํ๊ณ ๋์ผํ ๋ช
๋ น์ ์คํํ๊ฑฐ๋ ๋จผ์ del $__PYVENV_LAUNCHER__
ํธ์ถํ๋ฉด paver๊ฐ ์์๋๋ก ์คํ๋๊ณ shebang ๋ผ์ธ์ด virtualenv๋ฅผ ๊ฐ๋ฆฌํต๋๋ค.
xonsh๊ฐ ์์๋ ๋ ํด๋น ํ๊ฒฝ ๋ณ์๋ฅผ ์ง์์ผ ํฉ๋๊น?
https://github.com/python/cpython/pull/9516์ ๊ฐ๋ฅํ ๋ฒ๊ทธ ์์ ์ด
์ด ๋ฌธ์ ๋ ์ต๊ทผ ํ๋์ด ์์๊ธฐ ๋๋ฌธ์ ์๋์ผ๋ก ์ค๋๋ ๊ฒ์ผ๋ก ํ์๋์์ต๋๋ค. ๋ ์ด์ ํ๋์ด ์์ผ๋ฉด ํ์๋ฉ๋๋ค. ๊ณ์ ์ด์ด๋๊ณ ์ถ๋ค๋ฉด ๋๊ธ์ ์ถ๊ฐํ์ธ์. ๊ทํ์ ๊ธฐ์ฌ์ ๊ฐ์ฌ๋๋ฆฝ๋๋ค.
Python 3.7.6(Homebrew๋ฅผ ํตํด ์ค์น๋จ)์ด ์ค์น๋ Mojave์์ ์ฌ์ ํ ์ด์ ๋์ผํ ๋์์ด ํ์๋ฉ๋๋ค.
rewrite ๋ธ๋์น๋ก ํ์ธํ ์ ์๋์?
@gaborbernat rewrite
๋ถ๊ธฐ(fbdd782257d8eace7f5440a2b665f2ddb72e9db6)๋ฅผ ๋น๋ํ๋ ค๊ณ ํ๋ฉด python3 setup.py build
์์ ๋น๋ ์ค๋ฅ๊ฐ ๋ฐ์ํฉ๋๋ค.
...src/virtualenv/__init__.py", line 3, in <module>
from .version import __version__
ModuleNotFoundError: No module named 'virtualenv.version'
์ด ๋ฌธ์ ์ ๊ด๋ จ์ด ์์ด ๋ณด์ ๋๋ค.
์ฌ์์ฑ ๋ถ๊ธฐ(fbdd782)๋ฅผ ๋น๋ํ๋ ค๊ณ ํ๋ฉด python3 setup.py ๋น๋์์ ๋น๋ ์ค๋ฅ๊ฐ ๋ฐ์ํฉ๋๋ค.
์ฌ์์ฑ ๋ถ๊ธฐ๋ ๋น๋ ํ๋ก์ธ์ค๋ฅผ ์ ์ํ๊ธฐ ์ํด pyproject.toml
๋ฅผ ์ฌ์ฉํ๋ฏ๋ก pip๋ฅผ ์ฌ์ฉํ์ฌ ๋น๋๋ฅผ ์ํํด์ผ ํฉ๋๋ค( pip wheel .
.
๋น์ ์ด ์ป๋ ์ค๋ฅ๋ ๋ด๊ฐ ํ์ด์ฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๊ตฌ์ถํ๋ ์๋ก์ด ํ์ค ๋ฐฉ๋ฒ(PEP-517/518)์ ์ง์ํ์ง ์๋๋ค๋ setuptools ๋ฐฉ์์ ๋๋ค. ๊ธฐ๊ปํด์ผ setuptools ๋ฒ๊ทธ์ด์ง๋ง @pfmoore๊ฐ ์ง์ ํ๋ฏ์ด pip๋ฅผ ์ฌ์ฉํ์ฌ ํ ์ ๋น๋ํ๊ฑฐ๋ virtualenv ํด๋๋ฅผ ์ง์ ํ์ฌ ์ค์นํ๋ ๊ฒ์ด ๋ ์ข์ต๋๋ค(์๋์ผ๋ก ํ ์ ๋น๋ํ๊ณ ํ ๋ฒ์ ์ค์นํจ).
ํ ์คํธ ์ผ์ด์ค:
#!/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
์ด๊ฒ์ python3+virtualenv 16.7.9์์ ์คํจํ๊ณ python3+virtualenv-16.7.10.dev11+gfbdd782(์ฆ, rewrite
๋ถ๊ธฐ)์์ ํต๊ณผํฉ๋๋ค.
์์ ๊ฐ์ด ์ฌ์์ฑ์์ ์์ ๋์์ต๋๋ค.
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
๋๋์ด ์ ํํ ๋ฒ๊ทธ์ ๋ฌผ๋ ธ๋ค. ์ ์๊ฐ์๋ ๋งค์ฐ ์ฌ๊ฐํ ๋ฒ๊ทธ์ ๋๋ค. ๋๋ถ๋ถ์ด ๋งค์ฐ ํผ๋์ค๋ฝ๊ณ ์ธ์ ๋ฐ์ํ๋์ง ํ์ ํ๊ธฐ ์ด๋ ต๊ธฐ ๋๋ฌธ์ ๋๋ค.