Как заставить "python -m venv" напрямую устанавливать последнюю версию pip

Как часть шага компиляции для новой версии Python, я выбираю и запускаю get-pip.py, чтобы установить последнюю версию pip рядом с исполняемым файлом python:

$ /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)

У меня 25 таких версий под /opt/python, хотя я в основном использую пять последних версий каждой версии major.minor, которая не является EOL. Для настройки заказа я использовал для запуска virtualenv или мой virtualenvutils с -p /opt/python/X.Y.Z/bin/python возможность получить виртуальную среду с определенной версией.

В 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, так как это имело PendingDeprecationWarning по крайней мере, с 2014 года (как видно из результатов этого вопроса)

При расследовании замены virtualenv с python -m venv в virtualenvutils Я сначала создал новый 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 версия! Если вы используете его, вы получите:

Вы используете версию 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 лишенный virtualenv, а затем добавить 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

pip 18.0 из /opt/python/3.7.0/lib/python3.7/site-packages/pip (python 3.7)

Что вызывает /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 создает virtualenv с последними pip версия без возврата к сценариям, псевдонимам или с использованием нескольких команд? Имея последние pip установлен под /opt/python/3.7.0 явно недостаточно.

Есть два колеса в комплекте:

/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 проблема с версией

6 ответов

Хитрость заключается не в том, чтобы установить связанную версию pip (которая почти всегда будет устаревшей), а в том, чтобы использовать ее для установки самой последней версии из Интернета.

Стандартная библиотека venv предлагает --without-pipфлаг, который может здесь помочь. После создания виртуальной среды без pip вы можете "запустить" колесо surepip напрямую благодаря импортеру zip Python. Это быстрее и менее опасно, чем установка 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] = pathlib.Path(ensurepip.__path__[0]).glob('_bundled/pip*.whl'); 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 flags для достижения того же на Python 2.7.

Python 3.9's venv может получить --upgrade-depsвозможность автоматизировать это, см. https://bugs.python.org/issue34556 для получения дополнительной информации об этом.

Я использую upgrade-ensurepip обновить те pip а также setuptools файлы колеса, которые являются частью ensurepip пакет. Это не так элегантно, как возможность обновления ensurepip с помощью pip, но все же предпочтительнее делать это вручную.

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

Это ожидаемое поведение. python -m venv звонки python -m ensurepip установить pip и этот ответ показывает, что ensurepip установит только в комплекте версию даже с --upgrade вариант. Официального варианта обновления в комплекте нет. pip а также setuptools,

Ну, у меня также нет хорошей идеи, чтобы решить эту проблему, так как это просто спроектированное поведение. Я хотел бы дать два предложения:

  1. использование pipenv, Это действительно хорошо! И в будущем он станет официальным менеджером пакетов следующего поколения (хотя существует большая проблема, связанная со структурой текущего Pypi. Короче говоря, менеджер пакетов может определять зависимости только при загрузке всего пакета. Это создает огромные трудности для построение графика зависимостей.).

  2. Реализуйте свой обычай EnvBuilderНа самом деле есть официальный пример по этому поводу. И в примере, он также использует get-pip.py установить последнюю версию pip,

Вот версия сценария @ wim для powershell (7):

ПРИМЕЧАНИЕ. Это жестко запрограммировано в моем каталоге, но я исправлю это, когда выйду с работы:

Function Install-VEnv() {

   $py="python"
   if (!((Test-Path ./.venv) -and (Get-Item ./.venv).getType().Name -match 'DirectoryInfo')) {
      echo "creating venv..."
      # TODO fix prompt to not be hardcoded
      python -m venv .venv --prompt=tensorflow_models --without-pip
      if (!$?) {
         Write-Error "ERROR: Problem creating venv"
         return 1
      } else {
         $whl=$(python -c "import pathlib, ensurepip; [whl] = pathlib.Path(ensurepip.__path__[0]).glob('_bundled/pip*.whl'); print(whl)")
         echo "boostrapping pip using $whl"
         .venv/Scripts/python $whl/pip install --upgrade pip setuptools wheel
         . .venv/Scripts/Activate.ps1
      }
   } else {
      . .venv/Scripts/Activate.ps1
   }
}

Не стесняйтесь поправлять меня. Все мои знания о PowerShell были получены от призраков...

К вашему сведению, добавлен Python 3.9 --upgrade-deps варианты обновления pip + setuptools до последней версии на PyPI.

      python -m venv .venv --upgrade-deps

Если вы используете virtualenvwrapper, вы можете добавить команду обновленияpostmkvirtualenvсценарий. Он находится в~/.virtualenvsпапка по умолчанию.

Каждый раз, когда вы создаете новую виртуальную среду, pip будет обновляться. Я знаю, что это не идеальное решение, но оно работает.

      # vim ~/.virtualenvs/postmkvirtualenv 

pip install --upgrade pip
Другие вопросы по тегам