Pip: `pip install -U` обновляет уже удовлетворенные зависимости

Созданный на 9 июн. 2011  ·  23Комментарии  ·  Источник: pypa/pip

Если я pip install -U foo , я ожидаю, что будет установлена ​​последняя версия foo , а зависимости foo будут переустановлены, только если они еще не удовлетворены. Но на самом деле все зависимости переустанавливаются, даже если у меня уже установлены идентичные версии:


$ pip install -U django-supervisor
Downloading/unpacking django-supervisor
  Downloading django-supervisor-0.2.0.tar.gz
  Running setup.py egg_info for package django-supervisor
Downloading/unpacking supervisor (from django-supervisor)
  Downloading supervisor-3.0a10.tar.gz (438Kb): 438Kb downloaded
  Running setup.py egg_info for package supervisor
    no previously-included directories found matching 'docs/*.pyc'
    no previously-included directories found matching 'docs/.build'
Downloading/unpacking meld3>=0.6.5 (from supervisor->django-supervisor)
  Downloading meld3-0.6.7.tar.gz
  Running setup.py egg_info for package meld3
Installing collected packages: django-supervisor, supervisor, meld3
  Found existing installation: django-supervisor 0.1.1
    Uninstalling django-supervisor:
      Successfully uninstalled django-supervisor
  Running setup.py install for django-supervisor
  Found existing installation: supervisor 3.0a10
    Uninstalling supervisor:
      Successfully uninstalled supervisor
  Running setup.py install for supervisor
    no previously-included directories found matching 'docs/*.pyc'
    no previously-included directories found matching 'docs/.build'
    Skipping installation of /usr/local/ejucovy/django/lib/python2.6/site-packages/supervisor/__init__.py (namespace package)
    Installing /usr/local/ejucovy/django/lib/python2.6/site-packages/supervisor-3.0a10-py2.6-nspkg.pth
    Installing echo_supervisord_conf script to /usr/local/ejucovy/django/bin
    Installing pidproxy script to /usr/local/ejucovy/django/bin
    Installing supervisorctl script to /usr/local/ejucovy/django/bin
    Installing supervisord script to /usr/local/ejucovy/django/bin
  Found existing installation: meld3 0.6.7
    Uninstalling meld3:
      Successfully uninstalled meld3
  Running setup.py install for meld3
Successfully installed django-supervisor supervisor meld3
Cleaning up...

Мои «существующие установки» supervisor-3.0a10 и meld3-0.6.7 обе «успешно удалены», а затем устанавливаются идентичные версии.

upgrade auto-locked bug

Самый полезный комментарий

Я не думаю, что это дубликат № 49. Я прочитал # 49, говоря, что install -U foo не следует переустанавливать _ foo сам_, если он уже в последней версии - что отличается от того, следует ли переустанавливать foo уже удовлетворенные зависимости.

Это различие имеет значение для трудно собираемых библиотек, которые имеют частые выпуски, но довольно стабильные API - по большей части достаточно одной установки - я бы хотел переустановить ее только в том случае, если мои зависимости начнут использовать новые функции из этих вложенные зависимости (т.е. если требование больше не выполняется) - например:

  • foo 0.1 зависит от lxml>=2.3.0
  • foo 0.2 выпущен и зависит от lxml>=2.3.0 (та же зависимость)
  • lxml 2.4.0

Если я уже установил foo 0.1 и lxml 2.3.0 , и я pip install -U foo , я бы не хотел, чтобы он устанавливал lxml 2.4.0 . Он должен устанавливать lxml 2.4.0 тогда, когда foo начинает зависеть от lxml>=2.4.0 .

Все 23 Комментарий

По моему мнению, это известное поведение, не знаю, действительно ли это ошибка - я думаю, easy_install имеет такое же поведение.

Хотелось бы узнать мнение других.

PS: В StackOverflow возник вопрос, связанный с этим: http://stackoverflow.com/questions/5937756/why-is-pip-looking-for-download-cache-if-the-same-exact-package-is -уже-установить

Относится к выпуску # 49

Это ошибка, и это дубликат № 49.

Я не думаю, что это дубликат № 49. Я прочитал # 49, говоря, что install -U foo не следует переустанавливать _ foo сам_, если он уже в последней версии - что отличается от того, следует ли переустанавливать foo уже удовлетворенные зависимости.

Это различие имеет значение для трудно собираемых библиотек, которые имеют частые выпуски, но довольно стабильные API - по большей части достаточно одной установки - я бы хотел переустановить ее только в том случае, если мои зависимости начнут использовать новые функции из этих вложенные зависимости (т.е. если требование больше не выполняется) - например:

  • foo 0.1 зависит от lxml>=2.3.0
  • foo 0.2 выпущен и зависит от lxml>=2.3.0 (та же зависимость)
  • lxml 2.4.0

Если я уже установил foo 0.1 и lxml 2.3.0 , и я pip install -U foo , я бы не хотел, чтобы он устанавливал lxml 2.4.0 . Он должен устанавливать lxml 2.4.0 тогда, когда foo начинает зависеть от lxml>=2.4.0 .

Ах да, это немного другое. Даже если № 49 исправлен, потребуется некоторый дополнительный код для достижения желаемого поведения, когда зависимость не является последней версией, но все же удовлетворяет требованиям зависимости.

Думаю, если бы мы сделали это изменение, некоторых это удивило бы. Я понимаю, почему это желательно в определенных случаях, но я также могу видеть случаи, когда текущее поведение (минус № 49) является предпочтительным. Так что я нахожусь на заборе этого.

Подойдет ли дополнительная опция командной строки? pip install foo --upgrade vs pip install foo --upgrade-recursive ? (Или --upgrade-nonrecursive если важно сохранить текущее поведение с обратной совместимостью)

создание нерекурсивных обновлений по умолчанию обеспечит согласованность с другими менеджерами пакетов, такими как APT и Portage. и я думаю, что для такого поведения есть веская причина, заключающаяся в том, что оно позволяет избежать непреднамеренных побочных эффектов - если я хочу обновить пакет P, я хотел бы ввести команду в строках upgrade P , не upgrade P --but-not-other-things .

с другой стороны, я думаю, что команда «обновить все» (см. № 59) должна быть рекурсивной по умолчанию, поскольку «все» действительно должно означать «все» по умолчанию. в этом случае нерекурсивное поведение будет означать «обновить все пакеты, установленные напрямую, но не любые зависимости, которые не были установлены напрямую» (например, emerge --update @world Portage без --deep ).

Связанная проблема заключается в том, что если обновляемый пакет зависит от другого пакета, который уже установлен, но недоступен в репозитории, Pip завершится ошибкой и не сможет обновить запрошенный пакет, несмотря на то, что его зависимости выполняются.

Похоже, это происходит с -I, а также -U.

Поскольку -I означает --ignore-installed и предназначен для того, чтобы pip работал так, как если бы в данный момент ничего не было установлено, переустановка всего - это правильное поведение для -I . Таким образом, поведение здесь является ошибкой только для -U , а не для -I .

easy_install имеет другое поведение. easy_install не будет повторно устанавливать зависимости, если они уже выполнены.

это не функция или поведение, это ошибка.

это также действительно раздражает - тестирование распространения PIP для пакета фреймворка или обновление одного дополнения фреймворка означает необходимость переустановки всей фреймворка и всех его зависимостей. эти ненужные загрузки и установки - пустая трата времени и ресурсов.

для тех, кому просто нужен способ сделать это _now_, если не считать изменения поведения / кода на "-U"

Думаю, это дает желаемый результат, правда?

обновить только требования верхнего уровня:

  • pip install -U --no-deps REQS // обновляет только верхний уровень
  • pip install REQS // этот второй проход установит любые _new_ зависимости от обновления

В простейшем случае этого достаточно, но я не думаю, что это работает для файла requirements.txt или если есть зависимости, для которых установлены обновления install_requires. У нас есть сложный сценарий, который выполняет различие нашего файла requirements.txt и более или менее выполняет то, что вы описываете, но он не обрабатывает глубину обновления> 1.

Что до некоторой степени усложняет ситуацию, так это то, что многие пакеты django комментируют или удаляют свои строки install_requires из-за этой ошибки; в противном случае у них будет установлена ​​некоторая альфа-версия django (это был наш опыт, и я видел это в выпусках github многих известных пакетов django.

Привет, @fdintino , я

для случая, когда требование верхнего уровня имеет новую зависимость «install_requires», поэтому я упомянул команду второго прохода для их установки.

в случае, когда есть «зависимости, у которых есть обновления для install_requires», я не уверен, что следую за вами там. вы бы только обнаружили и захотели действовать в соответствии с этим, если бы хотели выполнить полное рекурсивное обновление, верно?

Только если вы больше не соответствуете требованиям. Так, например, если я обновил django-sentry, а django-sentry требовал django-celery>=2.5.4,django-celery<3.0 где раньше требовалось django-celery>=2.5.3,django-celery<3.0 (возможно, из-за исправления ошибки или новой функции), и в настоящее время у меня есть django-celery==2.5.3 , тогда я ожидал бы, что он обновит django-celery для удовлетворения требований, как это делает мой патч. Однако, если бы у меня оказался django-celery==2.5.4 я бы не ожидал, что он обновит сельдерей. В случае с сельдереем это не имеет большого значения, но когда в пакетах есть Django>1.2,Django<=1.4 , а проекты часто написаны для Django 1.2, 1.3 или 1.4, неожиданное обновление django может стать огромной головной болью.

спасибо @fdintino . Я слежу сейчас. вы не хотите отключать все рекурсивное поведение (которое будет выполнять необходимые обновления для выполнения требований), просто хотите остановить рекурсивные «принудительные» обновления.

кстати, ваш комментарий обрезан из-за форматирования. может захотеть исправить это для других.

Я опубликовал суть, которая мешает достижению желаемого поведения с помощью 2 команд в последовательности, упомянутой выше.
Не то чтобы это сводило на нет желание получить этот билет или тягу, но мне было полезно подтвердить, как
это работает в настоящее время и что возможно в настоящее время.
(подсказка: в примере «b» - это параллель с django, о котором упоминалось как о проблеме)

https://gist.github.com/3088149

Комментарий приветствуется по сути, если это не сценарий.

Я заметил, что это было открыто давно.

Я обнаружил, что в моей версии pip теперь есть возможность делать

pip install --upgrade --upgrade-strategy=only-if-needed package

Это кажется желаемым, хотя и довольно многословным. Лично я думаю, что было бы здорово, если бы это было по умолчанию, но, может быть, уже слишком поздно что-то менять.

Если уже поздно менять дефолт, то думаю это можно закрыть?

В https://github.com/pypa/pip/issues/3871#issuecomment -247789343 я упомянул то, что, по моему мнению, будет тем путем, которым мы собираемся двигаться вперед, воспроизводя здесь:

Вернемся к этому сейчас. Вот что, я думаю, нам следует делать:

  1. Добавьте --upgrade-strategy = [eager / non-eager] в pip vX, который по умолчанию равен eager , и разрешите людям отказаться от стратегии без желания. Это позволит нам проводить тестирование в реальном мире от людей, не заставляя менять всех сразу.
  2. После рассмотрения любых отзывов от 1. измените значение по умолчанию --upgrade-strategy на non-eager в pip vX + 1. Это принесет нам много пользы в реальном мире, заставив всех измениться, но даст выход людям, которые по какой-либо причине сломались из-за изменения.
  3. После того, как мы рассмотрим все отзывы от 2., обратите внимание на то, что --upgrade-strategy в pip vx + 2 не рекомендуется (будет удалено в соответствии с нашей обычной политикой устаревания).

У этого будет больше времени, прежде чем отсутствие желания станет по умолчанию, но это позволяет нам замедлить его поэтапно, чтобы убедиться, что нет какого-то варианта использования, который будет уходить от этого. В идеале, я думаю, мы хотели бы в конечном итоге избавиться от флага --upgrade-strategy . Кажется, что такой флаг просто вызывает проблемы с поломкой, потому что по сути требует, чтобы мы дублировали наше тестирование обновления, чтобы действительно полностью протестировать вещи. Я действительно думаю, что это хороший флаг, который нужно добавить на данный момент, чтобы разрешить фазу и устранить любые поломки.

Хорошо, звучит хорошо, я дождусь завершения шага 2. Кажется, что другой выпуск дублирован, но уже закрыт.

@xavfernandez @dstufft Можно его закрыть или подождем, пока не переключится по умолчанию?

Вероятно, подождем, пока не переключатся по умолчанию.

Закрытие, поскольку # 4500 был объединен

Была ли эта страница полезной?
0 / 5 - 0 рейтинги