簡體   English   中英

如何讓“python -m venv”直接安裝最新的pip版本

[英]How to get "python -m venv" to directly install latest pip version

作為新 python 版本編譯步驟的一部分,我獲取並運行get-pip.py ,以便在 python 可執行文件旁邊安裝最新的 pip:

$ /opt/python/3.7.0/bin/python --version
Python 3.7.0
$ /opt/python/3.7.0/bin/pip --version
pip 18.0 from /opt/python/3.7.0/lib/python3.7/site-packages/pip (python 3.7)

我在/opt/python下有 25 個這樣的版本,盡管我主要使用不是 EOL 的每個 Major.minor 版本的五個最新版本。 為了設置環境,我曾經使用-p /opt/python/XYZ/bin/python選項運行virtualenv或我的virtualenvutils以獲得具有特定版本的虛擬環境。

在 Python 3.7 中,這會給出 imp 模塊棄用警告:

$ virtualenv -p /opt/python/3.7.0/bin/python /tmp/py37virtualenv
Running virtualenv with interpreter /opt/python/3.7.0/bin/python
Using base prefix '/opt/python/3.7.0'
/opt/util/virtualenvutils/lib/python3.6/site-packages/virtualenv.py:1041: DeprecationWarning: the imp module is deprecated in favour of importlib; see the module's documentation for alternative uses
  import imp
New python executable in /tmp/py37virtualenv/bin/python
Installing setuptools, pip, wheel...done.

我幾乎不希望這會在 virtualenv 中得到解決,因為至少從 2014 年開始就有PendingDeprecationWarning (從這個問題的輸出中可以看出)

在調查替換virtualenvpython -m venvvirtualenvutils ,我首先創建一個新的venv用手基於虛擬環境:

$ /opt/python/3.7.0/bin/python -m venv /tmp/py37venv
$ /tmp/py37venv/bin/pip --version
pip 10.0.1 from /tmp/py37venv/lib/python3.7/site-packages/pip (python 3.7)

那有一個舊的pip版本! 如果你使用它,你會得到:

您使用的是 pip 版本 10.0.1,但是版本 18.0 可用。
您應該考慮通過“pip install --upgrade pip”命令升級

在使用virtualenv創建的虛擬環境中,您會立即獲得最新版本:

$ /tmp/py37virtualenv/bin/pip --version
pip 18.0 from /tmp/py37virtualenv/lib/python3.7/site-packages/pip (python 3.7)

我可以運行創建后步驟:

/tmp/py37venv/bin/pip install -U --disable-pip-version-check pip 

這將需要額外的時間。 如果pip有一些安全更新,這意味着運行非安全版本以獲得安全版本,這是一個理想的攻擊點。

virtualenvutils執行多個步驟來創建pip -less virtualenv 然后使用get-pip.py添加pip get-pip.py 從命令行這不是那么簡單:

$ /opt/python/3.7.0/bin/python -m venv --without-pip /tmp/py37venvnopip
$ /tmp/py37venvnopip/bin/python -c "from  urllib.request import urlopen; response = urlopen('https://bootstrap.pypa.io/get-pip'); open('/tmp/tmp_get_pip.py', 'w').write(response.read())"
$ /opt/python/3.7.0/bin/python /tmp/tmp_get_pip.py
......
$ /opt/python/3.7.0/bin/pip --version

來自 /opt/python/3.7.0/lib/python3.7/site-packages/pip (python 3.7) 的 pip 18.0

是什么導致/opt/python/3.7.0/bin/python -m venv采用舊的pip版本? 3.7.0 發布時那個版本可用嗎?

如何以某種方式更新我在/opt/python/3.7.0下的安裝,以便使用/opt/python/3.7.0/bin/python -m venv創建一個具有最新pip版本的 virtualenv,而無需恢復到腳本、別名或使用多個命令? /opt/python/3.7.0下安裝最新的pip顯然是不夠的。

有兩個捆綁的輪子:

/opt/python/3.7.0/lib/python3.7/ensurepip/_bundled/setuptools-39.0.1-py2.py3-none-any.whl
/opt/python/3.7.0/lib/python3.7/ensurepip/_bundled/pip-10.0.1-py2.py3-none-any.whl

我懷疑我需要更新這些。 有沒有比手動更新更好的方法? /some/python -m venv一些選項會很好。

(並且運行/some/python -m ensurepip --upgrade不起作用)


運行已棄用的/opt/python/3.7.0/bin/pyvenv具有相同的舊pip版本問題。

訣竅不是安裝pip 的捆綁版本(它幾乎總是過時的),而是使用它來安裝來自 Internet 的最新版本。

標准庫venv提供了一個--without-pip標志,可以在這里提供幫助。 創建沒有 pip 的虛擬環境后,您可以直接“執行”ensurepip 的輪子,這要歸功於 Python 的 zip 導入器。 這比安裝 pip 然后立即使用相同的 pip 安裝卸載自身並升級更快,也更簡單。

代碼勝於雄辯,所以這里是我描述的過程的示例 bash 函數:

# in ~/.bashrc or wherever

function ve() {
    local py="python3"
    if [ ! -d ./.venv ]; then
        echo "creating venv..."
        if ! $py -m venv .venv --prompt=$(basename $PWD) --without-pip; then
            echo "ERROR: Problem creating venv" >&2
            return 1
        else
            local whl=$($py -c "import pathlib, ensurepip; whl = list(pathlib.Path(ensurepip.__path__[0]).glob('_bundled/pip*.whl'))[0]; print(whl)")
            echo "boostrapping pip using $whl"
            .venv/bin/python $whl/pip install --upgrade pip setuptools wheel
            source .venv/bin/activate
        fi
    else
        source .venv/bin/activate
    fi
}

如果您更喜歡舊項目virtualenv ,它還提供--no-pip--no-setuptools--no-wheel標志以在 Python 2.7 上實現相同的目標。

Python 3.9 的venv可能會獲得一個venv --upgrade-deps選項來自動執行此操作,有關更多信息,請參閱https://bugs.python.org/issue34556

我使用upgrade-ensurepip來更新作為ensurepip包一部分的那些pipsetuptools輪文件。 它不像能夠通過pip升級ensurepip那樣優雅,但它仍然比手動升級ensurepip可取。

https://pypi.org/project/upgrade-ensurepip/

這是預期的行為。 python -m venv調用python -m ensurepip來安裝pip並且這個答案表明即使使用--upgrade選項, ensurepip也只會安裝捆綁版本。 沒有任何官方選項來更新捆綁的pipsetuptools

好吧,我也沒有解決這個問題的好主意,因為它只是設計的行為。 我想給出兩個建議:

  1. 使用pipenv 真的很好! 並且未來會是下一代官方的包管理器(雖然目前Pypi的結構有很大的問題。總之,包管理器只能通過下載整個包來決定依賴。這給了一個巨大的難度構建依賴關系圖。)。

  2. 實現您的自定義EnvBuilder ,實際上有一個關於此的官方示例 在示例中,它還使用get-pip.py來安裝最新的pip

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM