pip 10 и apt: как избежать ошибок "Cannot uninstall X" для пакетов distutils
Я имею дело с устаревшим Dockerfile. Вот очень упрощенная версия того, с чем я имею дело:
FROM ubuntu:14.04
RUN apt-get -y update && apt-get -y install \
python-pip \
python-numpy # ...and many other packages
RUN pip install -U pip
RUN pip install -r /tmp/requirements1.txt # includes e.g., numpy==1.13.0
RUN pip install -r /tmp/requirements2.txt
RUN pip install -r /tmp/requirements3.txt
Во-первых, несколько пакетов устанавливаются с помощью apt
, а затем несколько пакетов устанавливаются с помощью pip
, pip
версия 10 была выпущена, и частью выпуска является это новое ограничение:
Удалена поддержка для удаления проектов, которые были установлены с помощью distutils. Установленные проекты distutils не включают метаданные, указывающие, какие файлы принадлежат этой установке, и поэтому фактически невозможно удалить их, а не просто удалить метаданные, говоря, что они были установлены, оставив при этом все фактические файлы.
Это приводит к следующей проблеме в моей настройке. Например, первый apt
Установок python-numpy
, Потом pip
пытается установить более новую версию numpy
например, /tmp/requirements1.txt
и пытается удалить старую версию, но из-за нового ограничения он не может удалить эту версию:
Installing collected packages: numpy
Found existing installation: numpy 1.8.2
Cannot uninstall 'numpy'. It is a distutils installed project and thus we cannot accurately determine which files belong to it which would lead to only a partial uninstall.
Теперь я знаю, что на данный момент есть несколько решений.
Я не смог установить python-numpy
через apt
, Однако это вызывает проблемы, потому что python-numpy
устанавливает несколько различных пакетов в качестве требований, и я не знаю, полагается ли другая часть системы на эти пакеты. И на самом деле, есть несколько apt
пакеты, установленные через Dockerfile, и каждый, который я удаляю, кажется, обнаруживает другой Cannot uninstall X
ошибка, и удаляет ряд других пакетов вместе с ней, на которые наше приложение может положиться, а может и не положиться.
Я также мог бы использовать --ignore-installed
вариант, когда я пытаюсь pip
установить вещи, которые уже были установлены через apt
, но опять же у меня та же проблема каждого --ignore-installed
аргумент, раскрывающий еще одну вещь, которую необходимо игнорировать.
Я мог бы приколоть pip
в более старой версии, которая не имеет этого ограничения, но я не хочу застрять с использованием устаревшей версии pip
навсегда.
Я ходил кругами, пытаясь найти хорошее решение, которое включало бы минимальные изменения в этот устаревший Dockerfile и позволяло приложению, которое мы развертываем с этим файлом, продолжать функционировать, как было. Любые предложения относительно того, как я могу безопасно обойти эту проблему pip
10 не в состоянии установить более новые версии distutils
пакеты? Спасибо!
ОБНОВИТЬ:
Я не поняла что --ignore-installed
может использоваться без пакета в качестве аргумента для игнорирования всех установленных пакетов. Я думаю о том, может ли это быть хорошим вариантом для меня, и спросил об этом здесь.
2 ответа
Это решение, к которому я пришел, и наши приложения работали без проблем в течение почти месяца с этим исправлением:
Все, что мне нужно было сделать, это добавить
--ignore-installed
к pip install
строки в моем dockerfile, которые вызывали ошибки. Используя тот же пример dockerfile из моего исходного вопроса, исправленный dockerfile будет выглядеть примерно так:
FROM ubuntu:14.04
RUN apt-get -y update && apt-get -y install \
python-pip \
python-numpy # ...and many other packages
RUN pip install -U pip
RUN pip install -r /tmp/requirements1.txt --ignore-installed # don't try to uninstall existing packages, e.g., numpy
RUN pip install -r /tmp/requirements2.txt
RUN pip install -r /tmp/requirements3.txt
Документация, которую я мог найти для --ignore-installed
было неясно по моему мнению (pip install --help
просто говорит "Игнорировать установленные пакеты (переустановка вместо)."), и я спросил о потенциальных опасностях этого флага здесь, но пока не получил удовлетворительного ответа. Однако, если есть какие-либо негативные побочные эффекты, наша производственная среда еще не увидела их последствий, и я думаю, что риск низкий / нет (по крайней мере, так было в нашем опыте). Я смог подтвердить, что в нашем случае, когда этот флаг использовался, существующая установка не была удалена, но всегда использовалась более новая установка.
Это то, что сработало для меня
pip install --ignore-Installed
или sudo pip install --ignore-installed
или (внутри блокнота juoyter) импорт sys!{sys.executable} -m pip install --ignore-installer
Для windows напишите
conda update --all
pip install --upgrade <Your package name>
ИЛИ
conda update --all
pip install <Your package name>
ИЛИ
pip install wrapt --upgrade --ignore-installed
pip install <Your package name>
из ОШИБКИ: Невозможно удалить "упаковку". во время обновления
Вы можете просто удалить numpy вручную, но оставьте остальные зависимости, установленные apt. Затем используйте pip, как и прежде, чтобы установить последнюю версию numpy.
#Manually remove just numpy installed by distutils
RUN rm /usr/lib/python2.7/dist-packages/numpy-1.8.2.egg-info
RUN rm -r /usr/lib/python2.7/dist-packages/numpy
RUN pip install -U pip
RUN pip install -r /tmp/requirements1.txt
Расположение numpy должно быть таким же. Но если вы хотите подтвердить местоположение, вы можете запустить контейнер без запуска файлов require.txt и выполнить следующие команды в консоли python внутри контейнера.
>>> import numpy
>>> print numpy.__file__
/usr/lib/python2.7/dist-packages/numpy/__init__.pyc