Pip: Сделать пакеты обновления команды установки по умолчанию

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

  • Версия Pip: Будущие версии, надеюсь, 10.0
  • Версия Python: все поддерживаются
  • Операционная система: все поддерживаемые

Основываясь на обсуждении в # 59, есть интерес сделать так, чтобы команда install обновляла установленный пакет по умолчанию. Такое поведение сделало бы pip совместимым с различными другими менеджерами пакетов в отношении поведения его команды install .

Этот вопрос предназначен для обсуждения, поскольку он заслуживает отдельного рассмотрения.

upgrade auto-locked

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

Хорошо, я игнорирую это обсуждение в течение нескольких дней, похоже, оно взорвалось как на сигнатуре, так и здесь :)

Я попытался прочитать, что происходит в этой теме, но она длинная и насыщенная информацией, поэтому я могу что-то пропустить, однако вы собираетесь получить стену слов.


Я не думаю, что будет совершенно справедливо сказать, что текущее поведение pip install -U <foo> делает людей более безопасными во всех отношениях. Да, я могу легко указать на некоторые проекты, такие как PyCrypto или криптография, где регрессии случаются редко (особенно регрессии безопасности), а новые выпуски обычно включают улучшения безопасности. Я думаю, что сосредоточение внимания только на этих случаях упускает другие случаи, например, случай, когда новая версия чего-то в PyPI вызвала регресс в безопасности. Есть, я думаю, еще два случая, оба из которых могут быть сведены к «обновлению или нет, вообще не влияет на безопасность», но различаются тем, подходит ли для них обновление или нет.

В целом, я не думаю, что рекурсивные обновления являются хорошим механизмом безопасности, и если одна из наших целей состоит в том, чтобы помешать людям запускать старые, небезопасные версии программного обеспечения (и я думаю, что это должна быть цель), чем я думаю, способ достижения это не для того, чтобы пытаться отказаться от поведения обновлений (и просто молиться и надеяться, что они запускают обновление через какое-то время), а вместо этого посвятить время целенаправленному решению проблемы. Это может быть что-то вроде pip list -o но он явно проверяет наличие проблем с безопасностью, он может проверять весь установленный набор пакетов на PyPI, чтобы увидеть, есть ли какие-либо известные проблемы безопасности с любым из них, или это может занять какой-то совершенно другой формат. Тем не менее, я думаю, что важно, чтобы это не было связано с какой-то частично связанной функциональностью и чтобы оно фактически охватило всю среду, а не только то, что использует пользователь. Если кто-то сделает pip install requests[security] один раз, а затем сделает pip install -U requests - мы полностью пропустим обновления pyopenssl и cryptogaphy и т. Д. если мы будем полагаться только на рекурсивные обновления.

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

Для pip install --upgrade <foo> у нас есть доказательства того факта, что наше текущее поведение является активно вредоносным, настолько, что проекты сбиваются с пути, лгут, чтобы предотвратить запуск такого поведения. Я думаю, что мы все можем согласиться с тем, что то, в чем люди чувствуют необходимость активно ниспровергать (не только в своих собственных проектах, но и защищать другие проекты), вероятно, потребует некоторых уточнений в том, как это на самом деле работает. В этом случае единственное реальное решение - попытаться избежать обновления (или понижения!), Где это возможно, и отдать предпочтение уже установленной версии, _ если_ пользователь явно не попросил ее изменить _или_ мы не сможем удовлетворить ограничения версии в противном случае . Я не вижу другого разумного способа реализовать это, которое не приведет к случайному запуску 30+ минутных сборок, что может привести к версии, менее подходящей для поставленной задачи (без использования оптимизированного BLAS или чего-то еще).

Выступая за то, чтобы оставить текущее поведение pip install --upgrade как есть, по сути, выступает против проектов, которые зависят от numpy, от честности в отношении того, зависят ли они от numpy. Если у кого-то есть другое предложение, как мы могли бы решить проблему numpy [1], то я думаю, им стоит поднять этот вопрос.

Я знаю, что одно предложение заключалось в добавлении флага --non-recursive-upgrade или своего рода флага --upgrade-strategy , но я думаю, что эти идеи в значительной степени служат только для усложнения ментальной модели, которую люди имеют в отношении pip. Для подавляющего большинства пакетов (особенно чистых пакетов Python, которые не имеют чувствительной к безопасности роли) не будет иметь большого значения, обновим мы их или нет, обновление стоит невысоко, но есть небольшой недостаток в том, чтобы держать их прикрепленными к установленная версия (если человек не найдет причину, функцию или ошибку для явного обновления _этого_ пакета). Однако здесь мы живем в крайних случаях, и я действительно вижу только два, которые имеют значение: пакеты, которые сложно обновить, и пакеты, чувствительные к безопасности, и, как я уже упоминал выше, я думаю, что если мы будем беспокоиться о том, чтобы люди Чтобы получить обновления безопасности, нам нужен реальный механизм для этого, а не слабая надежда на то, что важное обновление в какой-то момент попало в рекурсивное обновление. Учитывая, что я думаю, что нам нужна специальная поддержка для чувствительных к безопасности, для большинства пакетов это не имеет значения, а для случая, когда сложно обновить, на самом деле есть только один ответ, я думаю, что скрывать это за собственным флагом - плохая идея без обоснование текущих затрат на поддержание целого варианта для этого [2]. Я также думаю, что более консервативный подход должен быть наиболее очевидным подходом, иначе мы не решим проблемы для тех, кого сложно обновить, поэтому, если бы мы добавили новую опцию, мы все равно захотели бы изменить поведение --upgrade по умолчанию и добавьте какой-нибудь явный параметр, чтобы получить менее разговорчивый / безопасный подход к обновлениям.

Я не думаю, что мы должны позволять пакету помечать себя для готовых (или не желающих) обновлений. Я думаю, что это то, что должно быть согласовано между всеми пакетами, чтобы конечные пользователи могли иметь хоть какую-то надежду на разумную мысленную модель того, что pip собирается делать с их системой, когда они выполняют какую-то команду. При этом я мог видеть, как мы добавляем возможность отмечать версии как небезопасные в PyPI и предупреждать людей, если в их системе установлена ​​небезопасная версия (или, по крайней мере, если они собираются ее установить).

Итак, теперь, когда мы рассмотрели --upgrade , другая взаимосвязанная проблема заключается в том, что нам делать с pip install сравнению с pip install --upgrade . Лично я считаю, что мы должны сделать так, чтобы эти два значения означали одно и то же, _НАДЕЖДА_, может быть более разумным сначала сосредоточить обсуждение только на поведении --upgrade а пока оставить pip install покое. Как только мы разберемся с решением по обновлению, мы сможем заняться тем, что мы будем делать с самим pip install .

[1] Хотя, честно говоря, это не совсем связано с Numpy. Я снова и снова видел, как люди ломают свои системы или установки из-за непреднамеренного обновления. Это правда, что у многих проектов нет правильных нижних границ, но я считаю, что в равной степени верно (или более того), что у них также нет правильных верхних границ. Особенно важно то, что можно определить правильные нижние границы во время упаковки, но невозможно определить правильные верхние границы.

[2] Опции не бесплатны, они требуют затрат, и важно попытаться уменьшить их количество, насколько это возможно. Хотя обычно вы не можете свести их к нулю, шаблон, который я слишком часто вижу в программном обеспечении OSS, - это желание угодить всем, добавляя все больше и больше опций, хотя на самом деле это всего лишь механизм, позволяющий избежать принятия решения, которое может быть непопулярным с какая-то группа людей.

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

Хорошо, вот предложение:

Конечная цель (где мы хотим закончить)

  • pip install foo : обновляет foo до последней версии; также выполняет минимальный набор установок / обновлений, необходимых для удовлетворения зависимостей новой версии
  • pip install -U foo / pip install --upgrade foo : идентично pip install foo (за исключением, может быть, они должны в конечном итоге выдать какое-то предупреждение?); сохранен для обратной совместимости
  • pip require foo : то же, что и текущий pip install foo ; имеет тот же эффект, что и установка пакета с Requires-Dist: foo . Это странная низкоуровневая операция, которую не следует подчеркивать в документации, но мы оставляем ее на данный момент, чтобы обеспечить менее ухабистый переход, плюс она раскрывает значимую операцию, которую мы должны поддерживать в любом случае ( Requires-Dist обработка), так что это, вероятно, полезно для некоторых сценариев использования.
  • pip install --upgrade-recursive foo : то же, что и текущая pip install --upgrade foo - гарантирует, что foo является последней версией _и_ гарантирует, что все транзитивные зависимости являются последней версией. Это странный маргинальный вариант, который не следует подчеркивать в документации, но мы оставим его пока, чтобы обеспечить менее ухабистый переход.
  • pip install --upgrade-non-recursive foo : то же самое, что и будущее pip install foo , но явно для обеспечения менее ухабистого перехода.

Вариант перехода А

  • Фаза 0: что у нас сейчас - pip install foo не обновляется, pip install --upgrade foo выполняет рекурсивное обновление, pip require foo & pip install --upgrade-recursive foo - ошибки
  • Фаза 1:

    • мы добавляем pip require foo , pip install --upgrade-recursive foo , pip install --upgrade-non-recursive foo .

    • pip install foo и pip install --upgrade foo продолжают действовать так же, как и сейчас, но изменяются, чтобы проверить, что они _would_ сделали бы, если были установлены --upgrade-non-recursive , и выдают предупреждение об устаревании всякий раз, когда они актуальны. делать отличается от того, что они будут делать в будущем.

    • Пользователи, которые хотят отказаться от будущего поведения (и отключить предупреждения), могут использовать обычную конфигурацию, чтобы установить --upgrade-non-recursive по умолчанию (например, добавив [install] upgrade-non-recursive = yes к pip.conf )

  • Фаза 2:

    • pip install foo и pip install --upgrade foo переключаются на новое поведение.

Вариант перехода B

ПОЦЕЛУЙ: пропустить фазу 1 и перейти непосредственно от фазы 0 к фазе 2. Обоснование: неясно, действительно ли это что-то сломает, люди будут несколько сбиты с толку и раздражены в любом случае, вполне возможно, что они будут больше сбиты с толку и нас раздражает поэтапный переход, а не реальное изменение, у нас ограниченные ресурсы, и мы стремимся попасть в блестящее новое будущее.

В этой версии мы также, вероятно, можем пропустить добавление --upgrade-non-recursive , поскольку оно сразу становится избыточным, как только оно вводится.

Комментарий

Я вроде как ожидаю, что все будут сопротивляться и настаивать на варианте перехода A вместо варианта перехода B. Но на самом деле я был бы доволен любым из них, поэтому вместо упреждающего компромисса я позволю кому-то другому сделать это. приведите этот аргумент (если они захотят) :-).

Хм, я не вижу добавленной стоимости вашего pip require ? Похоже на дубликат pip install ? Или, может быть, pip install --no-upgrade ?

Я достаточно доволен вариантом Б.

Но я не слежу за вашим описанием. Вы говорите pip require foo : то же, что и текущий pip install foo . Значит, будет ошибка, если будет установлен foo? И pip install --upgrade-recursive foo : то же, что и текущий pip install --upgrade foo . Я думал, что есть проблемы с существующим поведением install --upgrade (помимо того, что оно не является значением по умолчанию) - где-то ведется целая куча дискуссий о необходимости SAT-решателя. Ваше предложение, чтобы мы ничего не делали с этими проблемами? Или я неправильно помню и на самом деле нет проблем с текущим поведением --upgrade ?

Меня устраивает вариант Б.

Мне не нравится идея команды pip require по тем же причинам, по которым мне не нравились команды split pip install и pip upgrade . Две команды, которые делают одно и то же, но не совсем заставляют людей решать, какую из них использовать заранее, а не использовать флаги. Я также считаю, что для логических флагов (тех, которые включают / выключают что-либо) хорошей практикой является наличие инверсии везде, где это имеет смысл, чтобы люди могли лучше составлять команды.

Имея это в виду, вот что я бы сделал:

  • pip install --upgrade ... теперь выполняет «минимальное» обновление по умолчанию, обновляя все, что указано в командной строке / файле требований, до последней версии, но обновляет только зависимости, если это необходимо.
  • pip install --no-upgrade ... ведет себя так же, как pip install , аналогично вашей команде pip require , и просто обеспечивает установку любой версии требований к именам.
  • pip install ... по умолчанию переключается с неявного --no-upgrade на неявное --upgrade .

Вы могли заметить, что нет ничего похожего на текущее поведение, перечисленное до сих пор, типа флага «обновить все в пути зависимостей до последней версии». Я сомневаюсь, действительно ли мы хотим что-то подобное (и если мы этого хотим, хотим ли мы сохранить это навсегда, или это будет просто временная прокладка для облегчения перехода). Еще одна вещь, о которой следует помнить при принятии решения, - это то, как теоретическая команда pip upgrade влияет на это решение. Другими словами, если у нас есть команда для обновления всех установленных элементов, предвидим ли мы, что люди когда-либо захотят обновить X и все его зависимости?

Если нам действительно нужно что-то вроде текущего поведения --upgrade , я думаю, что вижу два варианта:

  • --recursive / --no-recursive Чтобы включить старое или новое поведение (но что они будут делать, если выбрано --no-upgrade ? Тихое отключение? Ошибка?).
  • --upgrade-strategy=(minimal / recursive) для переключения между двумя разными стратегиями, немного более многословно, чем --[no-]recursive , но также упрощает добавление дополнительных стратегий, если мы когда-нибудь окажемся в нужде.

Что касается решателя зависимостей, я не думаю, что эти две проблемы действительно так сильно взаимосвязаны. Наше решение в настоящее время является проблемой как в случае pip install и в случае pip install --upgrade , и я считаю, что проблема с предлагаемыми изменениями будет и далее. Это то, что нужно исправить, но я не думаю, что это имеет какое-либо отношение к тому, что мы здесь делаем (хотя, вероятно, имеет какое-то отношение к гипотетической команде pip upgrade ).

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

Достаточно легко написать скрипт для отображения всех (рекурсивных) зависимостей пакета:

# reqs.py
import sys
from pkg_resources import get_distribution

def reqs(req):
    results = []
    queue = [get_distribution(req)]
    while queue:
        current = queue.pop()
        results.append(current)
        for r in current.requires():
            d = get_distribution(r)
            queue.append(d)
    return results

if __name__ == '__main__':
    print('\n'.join(sorted(set(d.project_name for d in reqs(sys.argv[1])))))

Затем вы просто выполняете pip install $(reqs.py foo) чтобы получить "нетерпеливую установку" foo и его зависимостей. Я уверен, что у этого подхода есть недостатки, но достаточно ли распространена проблема, чтобы требовать более сложного решения?

@pfmoore хорошо, что этот сценарий работает только в том случае, если не изменились зависимости между

При этом единственный реальный вариант использования, который я могу придумать, - это установка проекта в среду, в которой уже установлены компоненты, но при этом желательно иметь последнюю версию зависимостей. IOW, фреймворк вроде Pyramid может предпочесть, чтобы новые пользователи устанавливали его зависимости с помощью рекурсивного обновления. ОДНАКО, даже в этом сценарии (который является единственным, о котором я могу думать), если все описатели версии гипотетической пирамиды верны, то конечный пользователь должен ожидать, что он будет работать независимо (и это похоже на то, что люди уже получили бы в текущем поведении pip install с чем-то уже установленным).

Если кому-то действительно нужна «Пирамида и все ее зависимости в актуальном состоянии», это несколько лучше, чем предлагаемый способ сделать это (объединение двух предложений), который будет pip install Pyramid && pip upgrade (что не совсем то то же самое, поскольку pip upgrade будет делать больше, чем просто Pyramid).

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

Мне не нравятся как A, так и B. Мне не нравится идея введения новой команды, и я не хочу переключаться на новое поведение без некоторого периода "устаревшего" стиля для текущего поведения. Поэтому ниже я выдвинул собственное предложение.

Я не осведомлен о строгих требованиях к текущему поведению

И я нет. Тем не менее, я не хочу нарушать чей-то рабочий код, не сказав им. Я бы посчитал это грубым. «Не делай с другими того, чего не хочешь, чтобы другие поступали с тобой». Вот почему я думаю, что не хочу переключаться без предупреждения, как в варианте B

Если кому-то действительно нужна «Пирамида и все ее зависимости в актуальном состоянии», это несколько лучше, чем предлагаемый способ сделать это (объединение двух предложений), который будет заключаться в установке Pyramid && pip upgrade (что не совсем так. то же самое, поскольку апгрейд пункта сделает больше, чем просто пирамиду).

Насколько я понимаю, если кто-то хочет «обновить пирамиду и все ее зависимости», после перехода на новое поведение это pip install --upgrade-strategy=eager Pyramid . Это с радостью обновит Pyramid и его зависимости до последней версии, независимо от того, является ли обновление ненужным.

Я думал, что было ясно, что мы хотим предоставить как текущие «рекурсивные-последние», так и новые обновления по умолчанию «только в случае необходимости». Подчеркиваю, что мне нужно публиковать общепринятые идеи.


Предложение

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

    • Должны быть предоставлены флажки, позволяющие пользователю проверить новое поведение, которое будет введено. Использование флага (ов) в этой версии означало бы --upgrade .
    • _maybe_, pip install --upgrade предупреждает, что в следующем выпуске этот флаг будет отключен.
    • pip install предупреждают, что поведение изменится в следующем выпуске, и текущее поведение не будет доступно в следующем выпуске.

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

  2. Переключитесь на новое поведение в следующем выпуске основной версии.

    • Если кому-то действительно нужно текущее поведение, можно добавить флаг --no-upgrade . Но я не хочу этого видеть, если это кому-то действительно_ не нужно.

Bikeshed : параметры и флаги в 1. Я предпочитаю добавить --upgrade-strategy=(eager / non-eager / default) в качестве флага в 1 и переключить стратегию по умолчанию на eager в 2.

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

как обрабатываются зависимости

Равномерно не зависит от глубины. Пользователь может выбирать между активными и неактивными обновлениями. Они такие, как я определил в своей предыдущей статье.

что происходит с ограничениями (и когда они конфликтуют)

Я бы сказал, что бы ни случилось сегодня.

двоичный или исходный код

Обрабатывать в # 3785. А пока оставьте как есть.

Я думаю, было ясно, что мы хотели предоставить как текущие «рекурсивные-последние», так и новые обновления по умолчанию «только в случае необходимости».

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

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

  • Это увеличивает вероятность того, что что-то вроде sudo pip непреднамеренно сломает чью-то ОС, потому что это увеличивает вероятность того, что мы рекурсивно перейдем к зависимости, предоставляемой ОС (даже если пользователь, вызывающий pip, не знал, что это затронет ).
  • Некоторые библиотеки очень дороги в установке , особенно такие, как Numpy, где компиляция может занять 30+ минут.
  • Рекурсивное обновление приводит к большему оттоку установленного набора пакетов, что увеличивает вероятность того, что что-то, что уже работало, сломается из-за обновления до общей зависимости.

Первые два из них - это вещи, которые можно исправить, по крайней мере частично, другими решениями (и для которых это решение также не является полным исправлением). Вы можете исправить поломку ОС, сделав pip более умным, чтобы не возиться с файлами ОС по умолчанию. Колеса упрощают установку даже сложных библиотек, таких как Numpy, но не все имеет колесо, и если вы используете что-то, кроме Windows, OS X или manylinux1, то ваши шансы получить колесо практически равны нулю.

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

Конечно, это очень тонкая разница, и трудно выделить все точные преимущества (их было бы точнее описать как компромиссы, а не как прямой набор преимуществ). Я не знаю, является ли старое поведение чем-то таким, что в тех случаях, когда оно полезно, оно достаточно полезно, чтобы люди потрудились использовать для него флаг или нет. Если мы добавим флаг, его будет трудно когда-либо удалить, если мы не добавим его сейчас, мы всегда сможем добавить его снова в будущем, поэтому по этой причине я несколько склоняюсь к тому, чтобы оставить его и ждать, чтобы увидеть, сможем ли мы заставить людей просить способ вернуть прежнее поведение.

Я думаю, было ясно, что мы хотели предоставить как текущие «рекурсивные-последние», так и новые обновления по умолчанию «только в случае необходимости».

Нет, я так не думаю

Хм ... Я действительно думал, что оба поведения были сочтены полезными. Пример с пирамидой заставил меня задуматься. Он использует текущее поведение и делает именно то, что нужно.

Кажется желательным иметь возможность сказать «обновить pkg и все его (под-) * зависимости до последней версии». Я не хочу обновлять _все_ в своей экосистеме, я просто хочу получить последние исправления ошибок для pkg и зависимостей.

  • Некоторые библиотеки очень дороги в установке, особенно такие, как Numpy, где компиляция может занять 30+ минут.

Благодаря консервативному обновлению пакетов это происходит реже.

Изменить: вы упомянули об этом.

  • Рекурсивное обновление приводит к большему оттоку установленного набора пакетов, что увеличивает вероятность того, что что-то, что уже работало, сломается из-за обновления до общей зависимости.

Это _ требует_ исправления преобразователя зависимостей. Считаю это выходящим за рамки данного вопроса.

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

Это очень хорошо работает со мной. Добавляет, почему я хочу "устаревшую" версию для текущего поведения, чтобы люди просили оставить его, а не добавляли повторно.

Изменить: s / версия / поведение /


: confused: Есть комментарии по моему предложению выше?

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

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

Самая стабильная (с точки зрения новых, ранее не встречавшихся ошибок) программа - это программа, которая никогда не меняется.

Есть комментарии по моему предложению выше?

Меня немного беспокоит добавление предупреждения для каждого вызова pip install , но я не против - это, безусловно, более безопасный путь, который больше соответствует нашему типичному процессу отказа от поддержки и это дает людям возможность требовать возможности использовать старое поведение.

Я действительно думаю, что нам нужно либо полностью отказаться от флага --upgrade как часть этого (возможно, не использовать его и скрыть на долгое время), либо нам нужно добавить --no-upgrade чтобы получить вернуться к старому поведению pip install ... . Я не хочу, чтобы в нашей справке валялся довольно бесполезный флаг --upgrade . Итак, тогда вопрос для флага --[no-]upgrade состоит в том, видим ли мы вообще полезное текущее поведение pip install . И здесь у меня опять нет твердого мнения - мы могли бы снова использовать период прекращения поддержки как шанс увидеть.

Есть комментарии по моему предложению выше?

Честно говоря, мне действительно не нравится идея, что по сути каждый вызов pip install будет давать предупреждение о полном цикле основного выпуска. Кажется, что это гарантированно просто раздражает пользователей, и в результате мы, вероятно, не получим никаких полезных отзывов, а только множество жалоб на процесс.

Мои предпочтения остаются с подходом @njsmith - вероятно, подходом «просто

Я должен признать, что мне очень трудно понять влияние этих различных предложений на мое повседневное использование. Обсуждается много теории и крайних случаев, которые затемняют ключевые моменты. Я думаю, что какой бы процесс перехода мы ни приняли, кто-то должен поработать над четким описанием предлагаемых изменений и их воздействия в стиле «пресс-релиз», которое мы можем опубликовать на distutils-sig перед внесением изменений. Это должно позволить нам оценить реакцию более широкого сообщества. (Я не думаю, что для этого нужен PEP, но я думаю, что это нужно огласить).

Мое инстинктивное чувство состоит в том, что я буду (мягко) доволен новым поведением при обновлении «как можно меньше», слегка раздражен тем фактом, что «установка» теперь обновляется без явного флага (но, надеюсь, я привыкну к этому. достаточно быстро), а в остальном - безразлично. Мое основное использование, вероятно, останется pip install new_thing для установки нового пакета и руководства "получить все имена пакетов и сделать pip install <all of them at once> чтобы вручную имитировать" обновить все ". Ни одно из них не будет затронуто любое из предложений (за исключением того, что новая стратегия обновления «как можно меньше» позволит избежать нечетных нежелательных попыток обновления, которые мне навлекает текущее поведение).

Для меня переломный момент наступает, когда становятся доступными --prefer-binary и "обновить все". Это повлияет на мое использование, и до тех пор я не увижу никаких преимуществ (или проблем) с изменением стратегии обновления.

Честно говоря, мне действительно не нравится идея, что по сути каждый вызов pip install будет давать предупреждение о полном цикле основного выпуска. Кажется, что это гарантированно просто раздражает пользователей, и в результате мы, вероятно, не получим никаких полезных отзывов, а только множество жалоб на процесс.

Действительно. Я не думал об этом в спешке. Ой!

Я хочу сказать, что я действительно хочу, чтобы у самого pip было запущено устаревание основной версии с таким серьезным изменением в основной его команде. В любой форме я играю.

Я думаю, что выбор в отношении того, когда мы показываем предупреждающее сообщение, - это путь вперед.

Как выбрать? @njsmith предлагается только тогда, когда поведение отличается. Если не считать того факта, что это, по сути, удваивает объем работы, выполняемой при каждой установке, если мы хорошо публикуем (заранее и подробно), я думаю, что это хорошая идея.


редактировать

Или, может быть, не задумываясь. Он не будет показывать сообщение всем, как хотелось бы. Хотелось бы хоть раз показать всем.

Как насчет некоторой магии файла конфигурации, предлагающей пользователю установить флаг в файле конфигурации? Здесь пригодится флаг --upgrade-strategy=default или аналогичный.

Есть какие-нибудь альтернативные идеи для этого?


переломный момент наступает, когда становятся доступными --prefer-binary и "upgrade all". Это повлияет на мое использование, и до тех пор я не увижу никаких преимуществ (или проблем) с изменением стратегии обновления.

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

Подобно последней идею @pradyunsg «s, IIRC GIT шоу (вроде долго) сообщений для того, когда она введена или собирается ввести большие изменения , которые можно отключить, установив конфигурацию с помощью командной строки, описанная в сообщении. Пока мне это нравилось.

Временная опция отключения сообщения - не самое худшее из возможных действий.

@pradyunsg : Прежде чем мы перейдем к деталям стратегий устаревания ... есть ли шанс убедить вас, что подход «вариант Б» подходит? (Обычно я бы не стал пробовать, но, учитывая, что основные разработчики, такие как @dstufft и @pfmoore, не

  • Чем дольше мы откладываем переключение, тем дольше мы продолжаем вызывать раздражающее текущее поведение наших пользователей - обратите внимание, что в # 59 есть 199 комментариев от 56 участников, многие из них просто +1. Заставить их ждать еще год - тоже довольно грубо.
  • Сроки прекращения поддержки сложны и трудны - они, по сути, накладывают дополнительные расходы на пользователей. Pip получает 10 миллионов загрузок в месяц только из PyPI, поэтому, например, ваше предлагаемое сообщение будет показано не менее 10 миллионов раз. Умножьте на то, сколько времени потребуется, чтобы прочитать что-то подобное, принять какое-то решение, обновить какой-то файл конфигурации и т. Д., А затем, возможно, повторить это снова через год, когда значения по умолчанию фактически изменятся.
  • Если мы когда-нибудь собираемся осушить это болото, то в какой-то момент мы должны двинуться в путь. Ждать год между каждым улучшением действительно болезненно.
  • А циклы прекращения поддержки обходятся разработчикам дорого - у нас и так крайне, крайне мало ресурсов для разработчиков, так что тратить время на реализацию сложной логики устаревания, отслеживание графика, возвращение через год и напоминание себе о том, что мы решили и т. д. Это время, которое можно было бы потратить на улучшение склада, внедрение надлежащего преобразователя, продвижение --prefer-binary и т. д. и т. д. это _ более_ важно, чем другие вещи, которые можно было бы сделать в то время.

8.1.2 из-за сложной ошибки, связанной с взаимодействием между pip, pkg_resources и devpi, сломала кучу развертываний людей. Это отстой, но люди справились с этим. Учитывая наши ограниченные ресурсы, это факт, что иногда мы собираемся что-то ломать, а иногда оставлять сломанные вещи на долгие годы без прогресса и, как правило, причинять пользователям боль. Мы не можем это изменить, но мы можем, по крайней мере, лучше понять, какие _виды_ боли мы причиняем пользователям, и «установка начинает работать так, как многие пользователи уже ожидают» - это гораздо более продуктивный результат, чем у большинства :-).


@pfmoore :

Вы говорите pip require foo : то же, что и текущий pip install foo . Значит, будет ошибка, если установлен foo ?
Нет, прямо сейчас, если foo уже установлен, pip install foo ничего не делает и успешно завершает работу. Я думал, что pip require будет способом напрямую поговорить с преобразователем ограничений: «вот новое ограничение, убедитесь, что оно удовлетворено». Семантически значимый и четко определенный, но довольно низкоуровневый интерфейс для экспертов.

@dstufft : я нахожу pip install --no-upgrade foo довольно запутанным - судя по названию, я ожидал, что он будет делать что-то вроде ... попробуйте установить foo но выйдет ошибка, если foo имела зависимость, которая вынудила бы обновить то, что я уже установил? Что в некотором роде противоположно тому, что он делал бы на самом деле. Для меня операция require операция install концептуально действительно различны - см. Также комментарии Гвидо о том, как, если вы когда-нибудь обнаружите, что пишете функцию, которая принимает логический аргумент, и вы знаете, что ваш вызывающие будут передавать константу, а не переменную для этого аргумента, тогда у вас должно быть две функции. Таким образом, разделив его на новую команду, я пытался представить, как это могло бы выглядеть в мире, где мы добавили его ради него самого, а не просто для выполнения нашего обязательства иметь форму --no для --upgrade или что угодно. Но я также счастлив полностью отказаться от этого сейчас ...


Хорошо, как насчет стратегии:

  • 9.0 делает pip install foo = pip install --upgrade foo = нерекурсивное обновление
  • Мы делаем небольшую небольшую запись, объясняющую реальный эффект ( pip install foo теперь будет обновляться, если foo установлен; pip install --upgrade foo больше не будет обновлять все зависимости рекурсивно)
  • Мы предоставляем сценарий вроде @pfmoore выше, и в примечаниях к выпуску говорится: «Если вы действительно хотите рекурсивное обновление, попробуйте это ...»
  • Мы делаем мысленную заметку о том, чтобы рассмотреть возможность добавления команды pip require foo в будущем, если она окажется полезной, но отложите это на данный момент, потому что это не совсем приоритет, и легче добавить что-то, чем убрать.
  • Мы сохраняем --upgrade как запретную операцию на неопределенный срок, но убираем ее из --help , и в справочном руководстве просто написано «нет операции; сохранено для обратной совместимости». (Может быть, через несколько лет мы его полностью вырвем, а может, и нет - мне все равно, и я счастлив просто отложить это обсуждение до тех пор, пока не пройдет несколько лет.)

Это позволяет избежать наихудшего беспричинного выхода из строя (нет причин, по которым pip install -U foo становится серьезной ошибкой и делает недействительными тонны существующих руководств), но в остальном делает вещи радикально простыми, поэтому мы можем пропустить или отложить размышления о таких вещах, как --no-upgrade или наиболее идеальное написание для рекурсивных обновлений и быстрого развертывания важных частей.

Кажется желательным иметь возможность сказать «обновить pkg и все его (под-) * зависимости до последней версии». Я не хочу обновлять все в своей экосистеме, я просто хочу получить последние исправления ошибок для pkg и зависимостей.

Проблема в том, что во многих случаях не имеет смысла назначать какую-либо зависимость какому-либо конкретному зависимому. Например, у многих людей есть среды с ~ 30 различными установленными пакетами, из которых 1 - numpy, а 29 - пакеты, зависящие от numpy. Итак, если мне нужны новые исправления ошибок для астропии, должно ли это обновить мой numpy? Это может исправить некоторые проблемы с астропией, но может также сломать другие 28 пакетов, кто знает. Цепочка зависимостей Pyramid включает ряд широко используемых служебных библиотек, таких как zope.interface и repoze.lru и setuptools (почему? Idk). Таким образом, рекурсивное обновление Pyramid может сломать Twisted (что зависит от zope.interface и setuptools и ничего больше). Нет никакого способа, чтобы «мне нужны последние исправления ошибок для Pyramid» подразумевали «я хочу последние setuptools » в сознании большинства пользователей - но так pip install -U настоящее время интерпретирует это.

Подобно последней идею @pradyunsg «s, IIRC GIT шоу (вроде долго) сообщений для того, когда она введена или собирается ввести большие изменения , которые можно отключить, установив конфигурацию с помощью командной строки, описанная в сообщении.

Это именно то, откуда у меня возникла идея.

Пока мне это нравилось.

То же. Следовательно, я хотел бы видеть это в пипсах. Это апробированный процесс.

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

Могу ли я убедить вас, что подход «вариант Б» приемлем?

Может быть. Вы правы, компромиссы сложны, и ждать перехода в год - тоже не самое удобное занятие. Взлом определенных нишевых кейсов, которые не затрагивают всех, - это нормально. Это просто произойдет. Здесь мы меняем наиболее часто используемую команду pip (в документации пакетов и в других случаях). Делать это без надлежащего периода предупреждения может оказаться не лучшим решением. Этого также не следует делать, не дав людям времени на то, чтобы исправить свои инструменты / рабочий процесс и т. Д. Для работы с новым поведением.

С текущим предложением @njsmith я все еще не получаю надлежащего предупреждения и не даю людям предварительный обзор предстоящего (крупного) изменения. Это все, но этого достаточно, что мне не нравится это предложение. Если кто-то может убедить меня в том, что отказ от этих двух требований будет нормальным и можно должным образом проинформировать людей о том, что это, большое изменение, происходит каким-то другим образом, меня это устраивает.

Если мы правильно понимаем детали устаревания, это должно быть возможно реализовать таким образом, чтобы материал, предназначенный только для устаревания, оставался в одном модуле (модуле, как на английском языке; класс, функция или что-то еще), а в следующем главном release просто прекращает вызывать этот модуль и удаляет его. Таким образом, по крайней мере, минимизируется работа после прекращения поддержки.

59 содержит 199 комментариев от 56 участников, многие из них просто +1. Заставить их ждать еще год - тоже довольно грубо.

Им не нужно ждать еще год. Они могут просто подписаться на новое поведение. Мы просто даем время людям, чьи вещи сломались из-за изменений. Другие могут просто согласиться на более приятное поведение.

Мы сохраняем --upgrade как запретную операцию на неопределенный срок, но убираем ее из --help, и в справочном руководстве просто написано «нет операции; сохранено для обратной совместимости». (Может быть, через несколько лет мы его полностью вырвем, а может, и нет - мне все равно, и я счастлив просто отложить это обсуждение до тех пор, пока не пройдет несколько лет.)
[вырезать?]
Это позволяет избежать наихудшего беспричинного сбоя (нет причин, по которым pip install -U foo станет серьезной ошибкой и сделает недействительными тонны существующих руководств)

Если бы это не было очевидным, то это произошло бы в моем предложении 1. Никого не беспокоит присутствие -U без операции. Его отсутствие сделает недействительной документацию по многим пакетам и сломает все. Мы будем хранить его, пока он не станет достаточно редким, чтобы его можно было безопасно удалить. Это обсуждение должно произойти через несколько лет. (давайте отметим для этого 16 сентября 2018 г., ни с того ни с сего)

Независимо от того, изменю ли я свою позицию по предложению @njsmith , мы сохраним поддержки --upgrade после прекращения поддержки.


Нет никакого способа, чтобы «мне нужны последние исправления ошибок для Pyramid» подразумевали «я хочу самые последние инструменты установки» в сознании большинства пользователей - но это то, как pip install -U в настоящее время интерпретирует это.

Правда. Но это связано с отсутствием преобразователя зависимостей. После добавления он делает _ в точности то, что хотел пользователь. До тех пор мы можем сделать лишь так много. Добавление предупреждения в документацию о потенциальной поломке зависимостей на данный момент достаточно, ИМО, так как это поведение должно стать отказом. И это предполагает, что пакеты выполняют свои обещания, данные через номера версий. Если они сломаются, пип мало что может сделать, пока пакеты не уточнят свои спецификаторы версии.

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

Итак, если мне нужны новые исправления ошибок для астропии, должно ли это обновить мой numpy?

Нет, если это нарушит ваш график зависимостей. Ни то, ни другое, если он удалит ваш хорошо настроенный numpy. В первом случае требуется преобразователь зависимостей. Последнему нужно «сдерживать» апгрейды. Оба выходят за рамки данного обсуждения.

Пока мы их не получим, самое большее, что мы можем сделать, это сказать людям: «pip не всегда делает то, что нужно, и у нас нет ресурсов, чтобы это исправить. Мы будем благодарны за помощь».


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

Могу только сказать грустно, но это правда.

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

  • pip install обновляется без особого желания, обновляя зависимости только в случае необходимости.

    • TBD: если также хотите добавить флаг отключения, который зависит от пути устаревания

  • pip install --some-flag выполняет активные обновления, обновляя зависимости до последней версии, разрешенной спецификаторами версии.

    • TBD: при желании

  • --upgrade переходит в режим запрета. Он хранится в install --help , что задокументировано как «сохранено для обратной совместимости».

    • TBD, если он будет удален из справки, я скажу нет

  • pip require откладывается до тех пор, пока кто-нибудь не попросит об этом. Как указано ниже, этого не может быть. (править: позже выяснилось, что я был неправ ..: |)

Как только мы определились с требуемым поведением, я начну работать над реализацией. (Я все еще знакомлюсь с деталями реализации pip install и # 3194 прямо сейчас.)

Давайте закончим здесь поведение и то, как мы хотим сделать отказ от рекомендаций, и мы изменим названия опций в PR, который я в конечном итоге сделаю.


pip install --target <dir> задокументировано как "По умолчанию это не заменяет существующие файлы / папки в

. "

Поскольку при установке теперь начинается обновление (замена) по умолчанию, кажется более последовательным заменить существующие файлы и папки по умолчанию и предоставить некоторый флаг, если пользователь желает иметь более старое поведение - не заменять. AFAIK, этот флаг еще не определился. pip require имеет сходство. Итак, я думаю, что мы не можем откладывать обсуждение pip require и должны сделать это сейчас.

Перекрытие с pip install и необходимость в нем, представленная install --target заставляет меня хотеть иметь поведение require за флагом в install .

@pradyunsg :

Здесь мы меняем наиболее часто используемую команду pip (в документации пакетов и в других случаях). Делать это без надлежащего периода предупреждения может оказаться не лучшим решением. Этого также не следует делать, не дав людям времени на то, чтобы исправить свои инструменты / рабочий процесс и т. Д. Для работы с новым поведением.

Это наиболее часто используемая команда pip, но мы касаемся только двух странных угловых случаев: pip install foo где foo уже установлен, и pip install -U foo где foo имеет некоторую рекурсивную зависимость, которая устарела. Хотя я уверен, что какие-то неясные поломки будут, что бы мы ни делали, я не могу придумать каких-либо разумных инструментов или рабочих процессов, которые могли бы нарушиться из-за этого - вы можете привести пример того, о чем вы думаете?

Правда. Но это связано с отсутствием преобразователя зависимостей. После добавления он делает именно то, что хотел пользователь.

??? Понятия не имею, что вы здесь имеете в виду - Pyramid рекурсивно зависит от setuptools, и я считаю, что это демонстрирует, что «пакет и его рекурсивные зависимости» на самом деле не соответствуют какой-либо значимой концепции в ментальной модели пользователя. AFAICT это полностью ортогонально проблеме решателя зависимостей?

pip install --target <dir> ... Поскольку при установке теперь начинается обновление (замена) по умолчанию, кажется более последовательным заменить существующие файлы и папки по умолчанию.

Я думаю, что проблема с pip install --target <dir> заключается в том, что он вообще не устанавливается в среду - он используется для таких вещей, как поставка. А без среды различие между обновлением и установкой даже не имеет смысла. Мой голос заключается в том, что мы оставляем это в покое - текущее поведение в порядке, ИМО.

pip require имеет сходство.

Оно делает?

мы касаемся только двух странных угловых случаев: pip install foo, где foo уже установлен, и pip install -U foo, где foo имеет некоторую рекурсивную зависимость, которая устарела.

Хм ... Действительно. Хотя изменение является серьезным, я согласен с тем, что мы ломаем просто странные угловые случаи. Но я действительно хотел бы получить некоторый пользовательский ввод, прежде чем вносить изменения ... Мне кажется неправильным вносить такое изменение без устаревания.

Если все остальные здесь (в основном @pfmoore и @dstufft) скажут, что они предпочитают переход на продолжу реализацию предложения

Правда. Но это связано с отсутствием преобразователя зависимостей. После добавления он делает именно то, что хотел пользователь.

Пирамида рекурсивно зависит от setuptools, и я считаю, что это демонстрирует, что «пакет и его рекурсивные зависимости» на самом деле не соответствуют какой-либо значимой концепции в ментальной модели пользователя.

Я не согласен. Очень важно хотеть получить самую последнюю возможную версию пакета и его зависимостей. В качестве примера, если я обнаружил, что в моей текущей среде есть проблема, связанная с pkgA, я бы хотел проверить ее последние выпуски и все его зависимости, чтобы исключить возможность того, что это проблема, которая была исправлена ​​в новой версии. . Я думаю, что разумно ожидать, что это возможно.

Для ясности: давайте не будем использовать старое поведение по той простой причине, что оно дает ленивым людям возможность сохранить существующее поведение, если оно им подходит. Мы сохраним его, только если выясним какой-нибудь допустимый вариант использования. Если мы пойдем по пути устаревания, он станет устаревшим, но будет доступен до конца устаревания. Если кто-то хочет такого поведения, он скажет, что хочет, и мы вытащим это из осуждения и позволим ему остаться.

AFAICT это полностью ортогонально проблеме решателя зависимостей?

Решатель зависимостей вступает в игру, когда A и B оба зависят от C , A рекурсивно обновляется, нарушая C на B поскольку pip не заботится о спецификаторах версии B при обработке A . Это был пример, который вы привели, когда Pyramid, Twisted и zope.interface были A, B и C соответственно.

pip require имеет сходство.

Оно делает?

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

@njsmith

Нет, прямо сейчас, если foo уже установлен, pip install foo ничего не делает и успешно завершает работу.

Я вижу

>pip install xlrd
Requirement already satisfied (use --upgrade to upgrade): xlrd in c:\users\uk03306\appdata\local\programs\python\python35\lib\site-packages

Я не уверен в статусе выхода, я думал о пользовательском опыте. Приносим извинения, я был небрежен в своих формулировках - я имел в виду, что я «получаю сообщение об ошибке» (возможно, технически это предупреждение), а не то, что пип устанавливает код выхода на ошибку. Но в любом случае это мелочь.

Ответ на другие электронные письма:

Я согласен с @njsmith, что @pradyunsg, если вы все еще чувствуете, что мы должны предупреждать пользователей, то непременно разместите сообщение в distutils-sig (и даже в python-list, если вы считаете, что это оправдано) и объявите там план. Есть риск, что это приведет к еще большему количеству споров и споров, которые могут быть, а могут и не быть продуктивными, но такова природа изменений упаковки :-)

Я также согласен с тем, что не считаю «Пирамиду и все ее зависимости» особенно полезной вещью для обновления. Сама пирамида, конечно. И, возможно, Pyramid и _selected_ зависимости. И, конечно же, «все в этом virtualenv (который был настроен для моей разработки Pyramid)».

Что наводит на мысль - как часто люди, просящие обновления, будут лучше обслуживаться с помощью virtualenvs и upgrade-all? Я не могу говорить о рабочих процессах других людей, но я определенно так работаю. И, конечно же, для многих сред pip freeze и точные ограничения версии являются нормой, поэтому нетерпеливые обновления там неуместны.

Наконец, мы отделили от этого предложения «pip нуждается в решателе» - поэтому аргументы в пользу того, что eager полезен, когда у нас есть решатель, сейчас не актуальны. Текущее нетерпеливое поведение может нарушить зависимости, поэтому мы должны удалить его, а затем, возможно, снова ввести рабочую версию, когда у нас будет решатель и мы получим отзывы о том, что (неизменная версия) функция полезна для людей.

если вы все еще чувствуете, что мы должны предупреждать пользователей, то непременно разместите сообщение на distutils-sig (и даже на python-list, если вы считаете, что это оправдано) и объявите там план.

Я думаю, что объявление о distutils-sig звучит для меня нормально. python-list, я подумаю.

Есть риск, что это приведет к еще большему количеству споров и споров, которые могут быть, а могут и не быть продуктивными, но такова природа изменений упаковки :-)

Это компромисс. Думаю, я перенаправлю их в PR по продаже велосипедов и приму другие комментарии из списка рассылки ...

Быстрое исправление: мне действительно следовало упомянуть весь текст справки --target .

"" "Установить пакеты в

. По умолчанию это не заменяет существующие файлы / папки в. Используйте --upgrade для замены существующих пакетов вс новыми версиями. "" "

Если мы делаем --upgrade бездействующим, --target не должно зависеть от этого. Нам нужно в этом разобраться.

Наконец, мы отделили от этого предложения «pip нуждается в решателе» - поэтому аргументы в пользу того, что eager полезен, когда у нас есть решатель, сейчас не актуальны. Текущее нетерпеливое поведение может нарушить зависимости, поэтому мы должны удалить его, а затем, возможно, снова ввести рабочую версию, когда у нас будет решатель и мы получим отзывы о том, что (неизменная версия) функция полезна для людей.

Звучит неплохо. Думаю, мы можем отказаться от стремления к обновлению. При необходимости его легко добавить. Снимая его (после переключателя), не так уж и много. Я считаю, что не предоставлять его и пропагандировать использование virtualenv для работы - хорошая идея.

@pfmoore Я так понимаю, вы хотите пойти по пути отказа от поддержки.

Я также согласен с тем, что не считаю «Пирамиду и все ее зависимости» особенно полезной вещью для обновления. Сама пирамида, конечно. И Pyramid, и отдельные зависимости, вполне возможно.

Когда вы говорите так, становится понятно, почему то, что я сказал, не идеально.

Текущее нетерпеливое поведение может нарушить зависимости

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

Во всяком случае, я так понимаю, что было решено отказаться от нетерпеливых обновлений.

Нам нужно в этом разобраться.

Может быть, повторно использовать --force-reinstall ? Я недостаточно знаю об этих вариантах, чтобы быть уверенным ...


@dstufft Я жду ваших мнений по

Итак, остается только --upgrade и --target . (и голосование @dstufft )

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

Текущее нетерпеливое поведение может нарушить зависимости
Я думаю, что любое изменение пакета имеет потенциал.

В частности, текущее нетерпеливое поведение может оставить систему в состоянии, в котором заявленные требования зависимостей (которые не противоречат друг другу или иным образом нарушены) нарушаются, когда они не были ранее. Это неприемлемо, и это то, к чему должен обратиться "правильный решатель". Я понимаю, что для более простых обновлений «только по мере необходимости» риск такой поломки сводится к минимуму даже без решателя.

Итак, остается только --upgrade и --target .

Помимо изменения текста справки --target чтобы он не ссылался на --upgrade , я считаю, что --target здесь выходит за рамки. Текст справки

Установите пакеты в <dir> . По умолчанию это не заменяет существующие файлы / папки в <dir> . Используйте --upgrade для замены существующих пакетов в <dir> новыми версиями.

Предлагаю просто заменить его на

Установите пакеты в <dir> .

Предположительно, значение по умолчанию изменится (как при обычной "установке") на перезапись по умолчанию, и если вы не хотите перезаписывать, вы просто не запускаете команду установки (как если бы вы устанавливали в пакеты сайта) . Если пользователям нужно что-то более сложное, они могут разработать соответствующие команды, давайте не будем беспокоиться о попытках предлагать предложения (которые могут оказаться полезными на практике, а могут и не оказаться).

Текст справки

Установить пакеты в

. По умолчанию это не заменяет существующие файлы / папки в. Используйте --upgrade для замены существующих пакетов вс новыми версиями.

Предлагаю просто заменить его на

Установить пакеты в

.

Хм ... Вы уверены, что хотите убрать функционал без замены существующих файлов / папок?

Вы уверены, что хотите удалить функцию отказа от замены существующих файлов / папок?

Это не я защищал - @dstufft и @njsmith решительно утверждали, что "install" должна обновляться при наличии уже установленного пакета. Единственное, что я добавляю, это то, что я не думаю, что поведение должно отличаться только потому, что пользователь указал --target .

Возможно, необходима опция --no-replace , но в таком случае она должна применяться как к установкам --target и к установкам без --target .

Не по теме

Ценой придирчивости, крошечное предложение / запрос / подсказка / {any_you_want_to_call_it} уценки - оставьте пустую строку > в цитате блока, чтобы сделать ее непривлекательной ... В противном случае она просто сливается с цитатой более высокого уровня ...

> > > A
> >
> > B
> C
>
> D

А

B
C

D

Обратите внимание, как B и C вышли на один и тот же уровень цитирования, но D действительно получил dedent ...

Возможно, необходима опция --no-replace , но в таком случае она должна применяться как к установкам --target и к установкам без --target .

: +1:

Ценой разборчивости, крошечное предложение / запрос / совет по уценке

Спасибо. Я пытаюсь сделать предварительный просмотр, но упустил это.

В понедельник я начну свою работу по внедрению в мастерской. Мы почти определились почти со всем, и даже если @dstufft говорит, что мы хотим

Вот что я собираюсь начать реализовывать:

  • --upgrade остается, но закрывается. Это значение никогда нигде не используется.

    • Я держу его в --help .

  • pip install будет выполнять обновления без особого желания, обновляя зависимости только в случае необходимости.
  • Нет нетерпеливых вариантов обновления. Текущее поведение станет недоступным.
  • Будет реализовано --no-replace , которое не позволит устанавливать пакеты поверх других пакетов и двигаться дальше без ошибок (например, что текущий pip install pkgA делает для pkgB, когда pkgA не установлен, pkgB установлен, а pkgA зависит от pkgB) .

Думаю, мы решили оставить --upgrade на данный момент (для обратной совместимости), но не об устаревании и _eventual_ удалении. Следует ли его удалить, используя обычный цикл устаревания, начиная с версии 9.0 (я думаю, что это нормально, если мы удалим его в 10.0 / 11.0 ...)?


Кстати, я подумал, поскольку это изменение сделает следующую основную версию намеренно несовместимой с предыдущими версиями; Имеет ли смысл попытаться настаивать на исправлении некоторых других проблем в том же выпуске? Если да, то есть ли такие проблемы?

Это помогло бы максимизировать полезность нашего решения о нарушении обратной совместимости.

ждем комментария @dstufft

edit: Добавлено «в понедельник», перемещено.

Привет.

Приносим свои извинения за отсутствие активности на прошлой неделе ... Пришла еще одна срочная работа, которая отняла у меня немного времени. Так или иначе, я начал работать над реализацией этого вопроса.

@pradyunsg : Я не понимаю, для чего --no-replace . --target - это странный вариант, который несколько месяцев назад почти устарел и может сохраниться, а может и не выжить в долгосрочной перспективе, поэтому, если он специально для --target то это очень низкий приоритет, и я бы не стал '' пока не волнуйся об этом.

В настоящее время --target имеет _зависимость_ от --upgrade . Текущее (по умолчанию) поведение --target - не заменять файлы и папки, уже находящиеся в целевом каталоге. Передача --upgrade изменяет это для замены файлов и папок, уже находящихся в target-dir.

Поскольку install теперь по умолчанию заменяет (обновляет чтение) пакеты по умолчанию, кажется имеет смысл изменить поведение по умолчанию install --target соответственно. Это будет --upgrade бесполезным флагом для --target , чего мы и хотим ( --upgrade станет запретной операцией, которая в конечном итоге будет удалена). Затем необходимо будет ввести новую опцию - текущее поведение --target . Это --no-replace .

Затем, для согласованности, если --no-replace работает с запусками --target , он также должен работать с нецелевыми. AFAICS, последнее - новое поведение.

Я думаю, даже если --target не проживет очень долго, имеет смысл иметь --no-replace который работает независимо от --target . Я не знаю, захочется ли кому-нибудь эта функциональность без --target .

PS: Приносим извинения за засорение стольких рядных моноширинных блоков.

Я не думаю, что --target (и, в частности, его текущее поведение по умолчанию) достаточно важно, чтобы гарантировать добавление нового флага только для его сохранения. IMO, мы просто переключаем --target на замену по умолчанию и теряем возможность добавлять только новые файлы (что в любом случае может привести к нарушению настроек).

Отказ от обновления уже установленного пакета _это безопасная операция, но --target этого не делает, потому что у него нет доступа к информации «что установлено в данный момент».

Итак, измените поведение --target чтобы перестать беспокоиться об уже существующих каталогах, и просто замените их, печатая сообщение, как это делает? Даже без печати сообщений?

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

В настоящее время --target ничего не заменяет. Это необходимо, поскольку оно не может безопасно удалить / обновить (нет установленной базы данных пакетов с --target и нет гарантии, что новая версия не имеет другого набора файлов, чем предыдущая версия). Текущее поведение --upgrade --target (AFAICT) небезопасно.

Таким образом, --target должен сохранить свое текущее поведение. Это делает его несовместимым с новой установкой, но это нормально, это для совершенно другого варианта использования. У меня нет проблем с удалением --upgrade , и в результате --target теряет эту возможность - в любом случае это небезопасная операция.

Учитывая, что я не согласен с изменением поведения по умолчанию --target , нет необходимости в флаге --no-replace .

Я не уверен, что вы имеете в виду, говоря, что --target имеет зависимость от --upgrade .

В ходе обсуждения может быть полезно прочитать текущий текст справки --target .

"" "Установить пакеты в

. По умолчанию это не заменяет существующие файлы / папки в. Используйте --upgrade для замены существующих пакетов вс новыми версиями. "" "

Я не уверен, что вы имеете в виду под --target, имеющим зависимость от --upgrade.

Чтобы разрешить замену существующего материала.

Учитывая, что я не согласен с изменением поведения по умолчанию --target, нет необходимости в флаге --no-replace.

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


Я хочу избавиться от необходимости обращаться к --upgrade в справке --target.

Хорошо, позвольте мне перефразировать. Поведение --target должно (IMO) быть изменено только в одном отношении: --upgrade (и поведение, которое оно позволяет) должно быть удалено.

Если кто-то может продемонстрировать вариант использования для --upgrade (учитывая, что это может что-то сломать), то я готов пересмотреть эту позицию, но я не думаю, что стоит сохранять «на всякий случай».

Поведение --target должно (IMO) быть изменено только в одном отношении: --upgrade (и поведение, которое оно разрешает) должно быть удалено.

Хорошо. Это проясняет.

Если кто-то может продемонстрировать вариант использования --upgrade

Не я.

Для меня это тоже звучит нормально. Мне кажется неприятной бородавкой то, что --target использовал --upgrade для этой цели.

Я думаю, нам следует перенести дальнейшее обсуждение в # 3806, чтобы избежать двух веток комментариев с одновременным обсуждением одного и того же.

Вау, эта ветка стала критической. Позвольте мне просто добавить свое решительное противодействие изменению значения -U. Абсолютно нет необходимости ломать мышечную память наших пользователей - мы можем добавить новую опцию, если нам нужны нерекурсивные обновления. Тем не менее, каков вариант использования нерекурсивных обновлений, кроме «pip install named-thing»?

Например, я думаю, что можно сказать, что явно названные дистрибутивы обновляются неявно, а -U, если он указан, вызывает полностью рекурсивное обновление. во всех случаях без --ignore-dependencies pip будет рекурсивно проверять соответствие.

@rbtcollins : "нарушение мышечной памяти наших пользователей" кажется немного сильным - WRT -U , изменения в текущем предложении будут следующими: (a) pip install -U foo по-прежнему является законным и все еще обновляет foo , но теперь нерекурсивно, (б) он теряет особое поведение, когда объединение -U плюс --target означает «перезапись любых существующих файлов». Я предполагаю, что последнее изменение вас не слишком беспокоит, учитывая, что вы недавно пытались отказаться от --target и что у большинства пользователей нет мышечной памяти на -U --target (надеюсь !! ). Итак, я полагаю, вы конкретно говорите, что предпочитаете, чтобы pip install foo выполнял нерекурсивную установку foo , а pip install -U foo выполнял рекурсивную установку foo ?

Я мог бы смириться с этим, особенно в качестве переходного состояния, когда мы одновременно осуждаем -U , но у него определенно есть недостатки:

  • Рекурсивное обновление AFAICT никогда никому не нужно? У него очень серьезные недостатки, и даже в тех случаях, когда он имеет смысл, кажется, что семантика кода («пакет и его зависимости») случайно совпадают с семантикой пользователя («этот пакет + связанные пакеты, которые в голове думаю о доставке вместе как единое целое »). См. Мой пост наверху - во многих случаях нет смысла назначать некоторую зависимость какому-либо конкретному зависимому ..._ . Возможно, пользователи иногда думают: «Я хочу обновить свою экосистему Pyramid», но даже когда они это сделают, они не ожидают, что это приведет к обновлению инструментов настройки - но именно это и делает рекурсивное обновление. Так что в конечном итоге рекурсивное обновление кажется мне неправильным - возможно, здесь есть допустимый вариант использования, но если он есть, мы должны выяснить, как решить этот вариант использования напрямую.
  • Даже если требуется рекурсивный переключатель обновления, правильным долгосрочным решением для этого переключателя не может быть написания --upgrade . Неужели мы действительно хотим объяснять новым пользователям, что если они хотят обновить пакет, то правильный способ сделать это - _отключить_ переключатель --upgrade ?
  • Это также усложняет жизнь людям, пишущим документацию, если «лучшая доступная команда обновления» для pip> = 9 - pip install foo , а для pip <9 - pip install -U foo . Я не хочу направлять людей к рекурсивному обновлению, но я также не хочу путать их с номерами версий pip, так что мне добавить в свой учебник? OTOH, если pip> = 9 делает эквивалент pip install и pip install -U , тогда совет использовать pip install -U foo остается верным, только немного избыточным.
  • Кроме того, поддержка этих двух разных режимов сложна и раздражает - в pip уже слишком много режимов, которые сложны, плохо документированы, трудно поддерживать и не совсем делают то, что кому-то нужно. Если мы сможем упростить, избавившись от одного из них, то это здорово, и до сих пор аргументы в пользу рекурсивных обновлений были очень тонкими. AFAICT ни один другой пакетный менеджер не поддерживает это, и никто не жалуется. Даже вы, кажется, основываете свой аргумент (пока) на том, что «эта вещь существует, и мы не должны ее менять», а не на том, что «эта вещь действительно полезна и чего хотят наши пользователи» ...

Так что я бы предпочел, чтобы мы двинулись дальше и заставили pip install foo / pip install --upgrade foo делать очевидные вещи, которые делают все остальные. Я думаю, что мышечные воспоминания большинства пользователей будут приятно удивлены, когда начнут получать то, на что они изначально надеялись :-).

Комментарий @njsmith дает хорошее резюме того, почему мы это делаем.

Думаю, мне нужно сделать ссылку на https://gist.github.com/pradyunsg/4c9db6a212239fee69b429c96cdc3d73 отсюда. Это последнее "предложение", которое я написал в результате обсуждения этого вопроса. Там есть раздел о « @rbtcollins хотел бы прочитать.

@njs - я не думаю, что это слишком сильно: сейчас люди знают, что для получения последней версии они запускают 'pip install -U' X. Это единственная причина запускать install -U ever (сегодня) и поэтому его нарушение нарушает его основной вариант использования.

Поведение с --target действительно не тот случай, о котором я беспокоюсь.

FWIW Я не согласен с вашим анализом того, что люди хотят / не хотят. В большинстве проектов тестируется только небольшое количество перестановок версий: последняя с последней + последняя со стабильной, когда существует стабильная версия. На самом деле обновление всего безопаснее, чем обновление только указанного компонента, потому что спецификаторы более низкой версии обычно неверны. См. # 3188 для улучшения, которое значительно упростит тестирование более низких лимитов версии. Я потерял счет, сколько раз я «исправлял» проблему людей, говоря им «pip install -U»: у них был пакет с неправильным нижним минимумом.

Насколько я могу судить, фактическая основная вещь, которая движет вашим «это неправильно», - это # ​​2687 - именно здесь pip может делать правильные вещи.

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

Если люди запускают очень сложные venv, они выбирают сложность - обычно это а) полная установка Python и б) выделенные venv. Мы должны направить всех на b как можно больше, потому что это по своей сути более надежно, и это усиливает аргумент, который я выдвигаю, что по умолчанию должен быть безопасным и работать как можно ближе к тому, что было протестировано апстримом.

менеджеры пакетов wrt - 'apt install X' никогда не будет обновляться - он только устанавливает. «apt upgrade» глобален - он обновляет все ». DNF аналогичен AIUI. Я не изучал инструмент suse, но я ожидал бы аналогичного поведения из-за использования плоских идиомных дистрибутивов «там может быть только один».

Может, для этого стоит обсудить более высокую пропускную способность? Кажется, это указывает в довольно опасном направлении, ИМО.

@pradyunsg ваше утверждение о текущем статусе pip в https://gist.github.com/pradyunsg/4c9db6a212239fee69b429c96cdc3d73 фактически неверно: уже есть переключатель --no-dependencies, который перекрывает рекурсивный / нерекурсивный случай. 'pip install -U foo --no-deps && pip install foo' должен быть семантически эквивалентен 'upstall named packages by default' - и меня это устраивает.

Нет tl; dr . Прочтите это.


@rbtcollins

ваше утверждение о текущем статусе pip в https://gist.github.com/pradyunsg/4c9db6a212239fee69b429c96cdc3d73 фактически неверно: уже есть переключатель --no-dependencies, который закрывает рекурсивный / нерекурсивный случай

Я никогда не утверждал, что pip не предоставляет возможности выполнять неактивные обновления или что отсутствует --no-deps в описании или (в моей памяти) где-либо еще. Какая часть моего «утверждения о текущем статусе пипса», по вашему мнению, «фактически неверна»?

Обязательно подумайте о том, чтобы перечитать этот раздел и явно указать на любые «фактически неверные» моменты в комментарии к Gist (не здесь, это будет шум), чтобы я мог их исправить.

Это единственная причина запускать install -U когда-либо (сегодня), и поэтому его нарушение нарушает его основной вариант использования.

Никто не собирается ломать мир.

  • pip install -U pkg прежнему будет обновлять pkg чего хочет и заботит большинство людей. Это то, что происходит с зависимостями, которые изменились.
  • (Теперь нерабочий) -U/--upgrade будет оставаться до тех пор, пока не почувствуете, что он больше не нужен, потому что все ушли.

FWIW Я не согласен с вашим анализом того, что люди хотят / не хотят. В большинстве проектов тестируется только небольшое количество перестановок версий: последняя с последней + последняя со стабильной, когда существует стабильная версия.

Если разработчик пакета предоставляет плохие метаданные, это не _неправильное_ поведение на стороне pip, что он нарушил среду пользователя из-за этого. Разработчик пакета несет ответственность за обеспечение надлежащих ограничений версии. Я согласен, что # 3188 поможет разработчику пакета в этом.

Я не думаю, что неправильно ожидать, что люди улучшат метаданные, которые они предоставляют PyPI (и, следовательно, pip).

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

Согласовано. Я действительно думаю, что если это безопасное программное обеспечение, то пакетам безопасности следует уделить дополнительное внимание. Более того, любые пакеты, которые пропускаются при обновлении, явно указываются как таковые. Таким образом, кто-то, смотрящий на результат, узнает, что произошло, и определит, хотят ли они принять меры.

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

"явное лучше, чем неявное"

Если люди запускают очень сложные venv, они выбирают сложность - обычно это а) полная установка Python и б) выделенные venv. Мы должны направить всех на b как можно больше, потому что это по своей сути более надежно, и это усиливает аргумент, который я выдвигаю, что по умолчанию должен быть безопасным и работать как можно ближе к тому, что было протестировано апстримом.

Я согласен с тем, что всем следует чаще использовать виртуальные среды. Я также согласен с тем, что движение как можно ближе к восходящему потоку также является благоприятным. Мне кажется смешным, что вы используете слово «безопасный» для защиты поведения, которое незаметно (и часто) нарушает график зависимостей.

'pip install -U foo --no-deps && pip install foo' должен быть семантически эквивалентен 'upstall named packages by default'

Это. Вся мотивация этого PR состоит в том, чтобы предоставить pip install -U foo --no-deps && pip install foo как pip install foo потому что поведение, которое каждый хочет большую часть времени, должно быть доступно напрямую. Это было обсуждено и решено, что лучше не предоставлять никаких способов делать активные обновления.

Насколько я могу судить, фактическая основная вещь, которая движет вашим «это неправильно», - это # ​​2687 - именно здесь pip может делать правильные вещи.

В предыдущих обсуждениях (# 59, на pypa-dev) был сделан вывод, что поведение в # 2687 невозможно исправить до тех пор, пока не появится # 988, что может занять довольно много времени, и такое поведение рассматривается как более безопасный вариант. -земли тем временем.

Сегодня каждый раз, когда кто-то запускает pip install -U pkg , он рискует сломать какой-то другой пакет в своей среде. Несмотря на то, что риск останется прежним даже после этого PR, количество раз, когда действия pip приводят к нарушению среды, сокращается.

Я в порядке с этим

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

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

Может, для этого стоит обсудить более высокую пропускную способность?

Это идея, стоящая за "криком" на distutils-sig.

(удалено как опубликованное в неправильной теме)

Ваш аргумент состоит в том, что меньшее количество людей пострадает от отказа от обновления зависимостей, которые не должны / не должны быть изменены, когда кто-то предоставил -U. Я считаю, что пострадает больше людей:

  • он меняется с безопасного по умолчанию на небезопасный по умолчанию. Нельзя считать пользователей квалифицированными или заинтересованными в установлении того, какие пакеты чувствительны к безопасности, а какие нет. Модель UX, которая зависит от пользователей, выполняющих эту дополнительную работу, активно вредна.
  • он меняется с идеального в рекомендуемых случаях на консервативный в случае патологии и вредный в рекомендуемом случае

Учитывая эти два варианта:
A - пользователи уязвимы к проблемам безопасности и не знают, что они
B - пользователи иногда сталкиваются с нарушением среды из-за # 2687

Я не понимаю, как мы можем выбрать что-то другое, кроме Б. Было бы безответственно поступить иначе.

Извините за обрывочные ответы, но я заметил еще одну вещь: мы усложняемся - например, Cargo не имеет ничего общего с предлагаемым здесь мелкозернистым контролем. Во многом это связано с тем, что у языка есть лучшие примитивы для изоляции - например, Javascript и Java Rust может справиться с несколькими версиями пакета в наборе зависимостей - что делает нашу работу решения почти полностью нерелевантной, кроме случаев, когда люди хотят свернуть до одной версии , тогда как у нас нет выбора. Но я думаю, что нам нужно искать действительно веские причины для добавления сложности - не только в ядре pip, но и в пользовательской модели. Основное ожидание PyPI состоит в том, что все работают вместе все время; отказ от обновления по умолчанию в значительной степени противоположен этому.

Итак - наши ожидания не оправданы, или мы просто реагируем на ошибки в pip, где существует достаточно информации, чтобы, по крайней мере, работать лучше?

мы просто реагируем на ошибки в pip, где существует достаточно информации, чтобы, по крайней мере, работать лучше

Этот. Мы определенно можем сделать намного лучше, используя имеющуюся у нас информацию. Но грустно, что мы этого не делаем. Для этого тоже есть причины, но это не главная тема нашей дискуссии.

Учитывая эти два варианта:
A - пользователи уязвимы к проблемам безопасности и не знают, что они
B - пользователи иногда сталкиваются с нарушением среды из-за # 2687

Я думаю, они одинаково плохи. Дело в том, что пользователь может видеть, что его пакет безопасности не был обновлен, и он может (и должен) согласиться на это обновление. Это немного лучше, чем статус-кво ИМО.

Я не согласен с тем, что они одинаково плохи.

  • Пользователи в автоматизированных средах не будут видеть и просматривать выходные данные, поэтому они не будут знать, что пакет не был обновлен.
  • Пользователи, которые видят, не будут знать, что данный пакет чувствителен к безопасности.

Предлагаемое вами изменение перемещает пипс от модели «делай-то-что-что-нибудь» на-внимательно-проверять-каждый-вызов-внимательно, потому что он-может-молча сделал-то-что-то не так. Я ожидал, что это будет невероятно тревожным для системного администратора [которым я был, так что это не праздные предположения]. Однако у нас нет четко определенных персонажей, на которые можно было бы указать, чтобы позволить новым участникам pip легко усвоить это.

Однако я рискую сгореть в этом шаблоне разговора, поэтому я отключаюсь и отключаю проблему; мое предложение для разговоров с более высокой пропускной способностью - чего нет в списке подписей - остается открытым, если это полезно - @dstufft могут связаться со мной на видеовстречах, IRC или любом другом носителе реального времени.

Я все еще жду @pfmoore https://github.com/pfmoore или @njsmith
https://github.com/njsmith дает мне добро, что этот PR в порядке
и мы можем объявить то же самое на distutils-sig для комментариев от более крупного
зрительская аудитория.

Извини, я не понял, что ты сдерживаешься. Да, пожалуйста, продолжайте и
объявить. Очевидно, что PR необходимо будет обновить, поскольку эти обсуждения
прогресс, но это, безусловно, прекрасная отправная точка для этого процесса.

@rbtcollins Я не хотел быть слишком настойчивым. Прости за это.

разговор с более высокой пропускной способностью

Я не интерпретировал это как разговор в реальном времени. :пот:

модель безопасных вещей для тщательного рассмотрения каждого вызова, потому что он, возможно, молча сделал то, что не так

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

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


Теперь я думаю, что оба поведения (текущее и предложенное) не идеальны. Я изменю свою позицию на то, чтобы не поддерживать ни то, ни другое. Я напишу это письмо по адресу distutils-sig.

Кроме того, последнее, что мы хотим, - это чтобы pycrypto и друзья
оставаться без обновления в течение месяцев или лет, потому что люди не знают, что они должны
сделайте что-нибудь особенное, чтобы иметь обновленное безопасное программное обеспечение.

Если вы говорите, что пользователь делает pip install --upgrade django
(где django зависит, скажем, от pycrypto) в настоящее время обновляется pycrypto,
и в будущем не будет, тогда да, это изменение (и согласился, это может
приводит к тому, что pycrypto является более старой версией).

В последнее время было слишком много разногласий по вопросам безопасности, и
Я не хочу быть причиной возникновения еще одного. Так что все, что я скажу
здесь есть компромисс между обновлением криптографического программного обеспечения
по сравнению с нарушением пакета X путем обновления криптографической (или другой!) зависимости до
версия, которую X не может использовать как часть несвязанного pip install Y . Мой
личные предпочтения - это подход, который использует этот PR (но см. ниже), но
Я осознаю проблему. Один вопрос - что делают менеджеры пакетов Linux
делать? Будет ли apt-get install python-django обновлять уже установленный
и совместимый python-pycrypto ? После установленного пакета Linux
управленческий подход хорошо вписался бы в основу всего остального PR).

Обратите внимание, что «поддерживать мои данные в актуальном состоянии» (я полагаю, эквивалент apt-get upgrade ) - это то, для чего был предназначен pip upgrade-all (см.

59). Это не часть этого предложения. Мой предпочтительный ответ на ваш

беспокойство выше было бы сказать "правильный способ поддерживать пакеты безопасности в рабочем состоянии
на сегодняшний день pip upgrade-all "- на самом деле обновления безопасности _не должны_
подождите, пока не обновится какой-нибудь другой пакет. (Так же верно сказать, что
им не следует ждать, пока пользователь обновит всю свою систему, поэтому "настоящая"
ответ - pip install [-U] pycrypto но я думаю, что мы можем согласиться с тем, что
инерция пользователя, какова она есть, не всегда реалистична). Может быть
выше приведен аргумент в пользу этой подкоманды? Но я не уверен, что это
может выполнять приемлемую работу без надлежащего преобразователя зависимостей.

Также обратите внимание, что в идеальном мире pip никогда бы ничего не сломал, выполнив
апгрейд. К сожалению, пока мы не получим полный решатель зависимостей, это не
кейс. Я полагаю, что у нас были сообщения о случаях такой поломки. Поломка должна
быть редкими - но давайте будем честными, так же как и эксплойты безопасности. Мы обсуждаем
маловероятные (но потенциально сильные) сценарии здесь, и это
их нелегко судить (если бы это было так, никто бы никогда не купил лотерею
Билеты :-))

Я не очень хорошо разбираюсь в этой теме и связанных с ней нюансах для правильного ее обсуждения.

И я нет. Я думаю, что @rbtcollins поднял важный вопрос. Пинг @dstufft как один человек, которого я знаю, с достаточным пониманием как pip, так и безопасности, чтобы принять здесь обоснованное решение ...

@pfmoore да, это то, что я говорю, и я с ужасом смотрю на бочку миллионов сред, больше не получающих обновления для таких библиотек.

Я согласен с тем, что команда на обновление всей среды может помочь.

Что касается решающего аспекта - поломка всегда будет происходить даже с резолвером: резолвер не является причиной большинства поломок, которые я вижу, скорее случайные ошибки. Да, нам это нужно, но это не панацея.

@pradyunsg Не нужно извиняться - вы не сделали ничего плохого; Я занимался, когда устал и был в стрессе от мысли о том, что что-то, что я считаю плохим выбором, быть втолкнутым мастеру, если я не сразу пойму на это.

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

Это было бы чем-то отдельным от текущего изменения, и я не
все продумал, но мне интересно, нужны ли здесь пакеты
(или, возможно, отдельные выпуски) должны быть помечены как "критические", подразумевая, что
pip всегда должен пытаться обновить эти пакеты при обновлении всего, что
зависит от них - по сути, это более детализированная версия нетерпеливого
обновления. Тогда такие проекты, как pycrypto, могут пометить себя как критические.

Такой механизм может быть использован для злоупотреблений, но поможет ли это?

Такой механизм может быть использован для злоупотреблений, но поможет ли это?

Пожалуйста, нет. Плохая идея иметь что-то подобное в основном немодерируемом индексе, таком как PyPI. Помимо очевидной возможности злоупотреблений, это дополнительное поведение, которое потенциально может удивить пользователя. Я думаю, что есть способы лучше справиться с такой проблемой; лучше делегировать это конечным пользователям, чтобы они сами решали, что они считают важным.

@rbtcollins Я чувствовал, что я был причиной того, что ты чувствуешь, что

Думаю, у @dstufft уже достаточно вещей. Итак, FWIW, я расскажу, что я думаю о фронте безопасности, когда обновление по умолчанию не требуется. Если ничего другого, я узнаю что-нибудь новое.

Я не думаю, что кто-то запускает pip install --upgrade в производственной среде без закрепленных требований / ограничений. Я могу ошибаться в этом, но на самом деле они не должны. Если они это сделают, они уже откроются для выхода из строя своей производственной среды, как и сегодня. Опубликуйте это изменение, у них все еще есть этот риск (сниженный, но присутствующий), а также риск отсутствия последних обновлений безопасности. На самом деле, не закрепляя свои зависимости, я бы сказал, что они выбрали уязвимость в системе безопасности. Вы бы согласились с этим?

На мой взгляд, единственные люди, которые запускают pip install --upgrade - это те, кто делает это на своих локальных машинах, либо во время разработки приложения, либо в качестве конечных пользователей библиотеки. Насколько это на них влияет, я не знаю. Я ни в коем случае не осведомленный человек по этой теме.


Честно говоря, чем больше я думаю об этом, тем больше мне хочется сесть и написать решатель SAT на чистом Python для pip.

Хорошо, я игнорирую это обсуждение в течение нескольких дней, похоже, оно взорвалось как на сигнатуре, так и здесь :)

Я попытался прочитать, что происходит в этой теме, но она длинная и насыщенная информацией, поэтому я могу что-то пропустить, однако вы собираетесь получить стену слов.


Я не думаю, что будет совершенно справедливо сказать, что текущее поведение pip install -U <foo> делает людей более безопасными во всех отношениях. Да, я могу легко указать на некоторые проекты, такие как PyCrypto или криптография, где регрессии случаются редко (особенно регрессии безопасности), а новые выпуски обычно включают улучшения безопасности. Я думаю, что сосредоточение внимания только на этих случаях упускает другие случаи, например, случай, когда новая версия чего-то в PyPI вызвала регресс в безопасности. Есть, я думаю, еще два случая, оба из которых могут быть сведены к «обновлению или нет, вообще не влияет на безопасность», но различаются тем, подходит ли для них обновление или нет.

В целом, я не думаю, что рекурсивные обновления являются хорошим механизмом безопасности, и если одна из наших целей состоит в том, чтобы помешать людям запускать старые, небезопасные версии программного обеспечения (и я думаю, что это должна быть цель), чем я думаю, способ достижения это не для того, чтобы пытаться отказаться от поведения обновлений (и просто молиться и надеяться, что они запускают обновление через какое-то время), а вместо этого посвятить время целенаправленному решению проблемы. Это может быть что-то вроде pip list -o но он явно проверяет наличие проблем с безопасностью, он может проверять весь установленный набор пакетов на PyPI, чтобы увидеть, есть ли какие-либо известные проблемы безопасности с любым из них, или это может занять какой-то совершенно другой формат. Тем не менее, я думаю, что важно, чтобы это не было связано с какой-то частично связанной функциональностью и чтобы оно фактически охватило всю среду, а не только то, что использует пользователь. Если кто-то сделает pip install requests[security] один раз, а затем сделает pip install -U requests - мы полностью пропустим обновления pyopenssl и cryptogaphy и т. Д. если мы будем полагаться только на рекурсивные обновления.

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

Для pip install --upgrade <foo> у нас есть доказательства того факта, что наше текущее поведение является активно вредоносным, настолько, что проекты сбиваются с пути, лгут, чтобы предотвратить запуск такого поведения. Я думаю, что мы все можем согласиться с тем, что то, в чем люди чувствуют необходимость активно ниспровергать (не только в своих собственных проектах, но и защищать другие проекты), вероятно, потребует некоторых уточнений в том, как это на самом деле работает. В этом случае единственное реальное решение - попытаться избежать обновления (или понижения!), Где это возможно, и отдать предпочтение уже установленной версии, _ если_ пользователь явно не попросил ее изменить _или_ мы не сможем удовлетворить ограничения версии в противном случае . Я не вижу другого разумного способа реализовать это, которое не приведет к случайному запуску 30+ минутных сборок, что может привести к версии, менее подходящей для поставленной задачи (без использования оптимизированного BLAS или чего-то еще).

Выступая за то, чтобы оставить текущее поведение pip install --upgrade как есть, по сути, выступает против проектов, которые зависят от numpy, от честности в отношении того, зависят ли они от numpy. Если у кого-то есть другое предложение, как мы могли бы решить проблему numpy [1], то я думаю, им стоит поднять этот вопрос.

Я знаю, что одно предложение заключалось в добавлении флага --non-recursive-upgrade или своего рода флага --upgrade-strategy , но я думаю, что эти идеи в значительной степени служат только для усложнения ментальной модели, которую люди имеют в отношении pip. Для подавляющего большинства пакетов (особенно чистых пакетов Python, которые не имеют чувствительной к безопасности роли) не будет иметь большого значения, обновим мы их или нет, обновление стоит невысоко, но есть небольшой недостаток в том, чтобы держать их прикрепленными к установленная версия (если человек не найдет причину, функцию или ошибку для явного обновления _этого_ пакета). Однако здесь мы живем в крайних случаях, и я действительно вижу только два, которые имеют значение: пакеты, которые сложно обновить, и пакеты, чувствительные к безопасности, и, как я уже упоминал выше, я думаю, что если мы будем беспокоиться о том, чтобы люди Чтобы получить обновления безопасности, нам нужен реальный механизм для этого, а не слабая надежда на то, что важное обновление в какой-то момент попало в рекурсивное обновление. Учитывая, что я думаю, что нам нужна специальная поддержка для чувствительных к безопасности, для большинства пакетов это не имеет значения, а для случая, когда сложно обновить, на самом деле есть только один ответ, я думаю, что скрывать это за собственным флагом - плохая идея без обоснование текущих затрат на поддержание целого варианта для этого [2]. Я также думаю, что более консервативный подход должен быть наиболее очевидным подходом, иначе мы не решим проблемы для тех, кого сложно обновить, поэтому, если бы мы добавили новую опцию, мы все равно захотели бы изменить поведение --upgrade по умолчанию и добавьте какой-нибудь явный параметр, чтобы получить менее разговорчивый / безопасный подход к обновлениям.

Я не думаю, что мы должны позволять пакету помечать себя для готовых (или не желающих) обновлений. Я думаю, что это то, что должно быть согласовано между всеми пакетами, чтобы конечные пользователи могли иметь хоть какую-то надежду на разумную мысленную модель того, что pip собирается делать с их системой, когда они выполняют какую-то команду. При этом я мог видеть, как мы добавляем возможность отмечать версии как небезопасные в PyPI и предупреждать людей, если в их системе установлена ​​небезопасная версия (или, по крайней мере, если они собираются ее установить).

Итак, теперь, когда мы рассмотрели --upgrade , другая взаимосвязанная проблема заключается в том, что нам делать с pip install сравнению с pip install --upgrade . Лично я считаю, что мы должны сделать так, чтобы эти два значения означали одно и то же, _НАДЕЖДА_, может быть более разумным сначала сосредоточить обсуждение только на поведении --upgrade а пока оставить pip install покое. Как только мы разберемся с решением по обновлению, мы сможем заняться тем, что мы будем делать с самим pip install .

[1] Хотя, честно говоря, это не совсем связано с Numpy. Я снова и снова видел, как люди ломают свои системы или установки из-за непреднамеренного обновления. Это правда, что у многих проектов нет правильных нижних границ, но я считаю, что в равной степени верно (или более того), что у них также нет правильных верхних границ. Особенно важно то, что можно определить правильные нижние границы во время упаковки, но невозможно определить правильные верхние границы.

[2] Опции не бесплатны, они требуют затрат, и важно попытаться уменьшить их количество, насколько это возможно. Хотя обычно вы не можете свести их к нулю, шаблон, который я слишком часто вижу в программном обеспечении OSS, - это желание угодить всем, добавляя все больше и больше опций, хотя на самом деле это всего лишь механизм, позволяющий избежать принятия решения, которое может быть непопулярным с какая-то группа людей.

Спасибо за стену слов :). Несколько отзывов и несколько мыслей.

tl; dr: Я согласен с вами насчет стоимости опционов и ментальных моделей, связанных с pip и так далее. Я все еще очень боюсь последствий того, что вы предлагаете.

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

Ключевым моментом в _в любом_ случае является систематический автоматизированный процесс обновления, которого у нас сегодня нет. В отсутствие этого, я считаю, что обновление по умолчанию значительно лучше.

Что касается верхних и нижних границ: сегодня нет абсолютно никакой возможности получить правильные нижние границы. Вы правы, что в логическом смысле можно точно указать только нижние границы, но в действительности никто не заявляет их точно сегодня: - он полностью реагирует на ошибки от людей, когда они обнаруживают, что нижняя граница неверна после отладки. . И среди людей, с которыми я разговаривал, нет даже единого мнения о том, что _должно_ быть сделано, когда нижние границы взаимодействуют с необязательными вещами - должны ли люди обнаруживать особенности, или повышать нижнюю границу, или просто вылетать, если выбран какой-то несовместимый путь? Если бы у pip была предложенная мною версия select-old-version, то этого не было бы, и было бы намного разумнее предположить, что нижние границы будут разумными.

Но я _ буквально потерял счет_ количества неисправных сред, которые я исправил для людей, сказав им «pip install -U package».

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

pip используется в 3 разных контекстах IME:

  • поддержание производственной среды
  • создание свежей среды воспроизводимым способом - например, сборка контейнеров
  • тестирование

Что касается последних двух, меня не волнует алгоритм обновления, поскольку он детерминирован.
Что касается первого, меня очень волнует, и похоже, что то, что у нас есть, - это один проект, вызывающий большую часть боли из-за комбинации разрывов API и ABI - потому что у numpy действительно есть один из них?

ЕСЛИ существовало производственное обслуживание, позволяющее обновлять все, то я бы вообще не стал отказываться от предлагаемого изменения, чтобы установить его. Но это не так, и мы понятия не имеем, как долго он будет существовать - AIUI, команда, которая могла бы это сделать, фактически была перенесена обратно, поэтому мы должны ожидать, что у нас ее не будет?

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

да. Библиотеки, такие как scipy и scikit-learn, лгут pip, что они не зависят от numpy, чтобы pip не запускал получасовую переустановку нового numpy вместо возможно оптимизированного или даже самокомпилированного numpy.

ЕСЛИ существовало производственное обслуживание, позволяющее обновлять все, то я бы вообще не стал отказываться от предлагаемого изменения, чтобы установить его. Но это не так, и мы понятия не имеем, как долго он будет существовать - AIUI, команда, которая могла бы это сделать, фактически была перенесена обратно, поэтому мы должны ожидать, что ее не будет?

Я не думаю, что кто-то возражал против этого, за исключением того, что люди ждут, пока решатель закончит работу первым, потому что есть мнение, что без резолвера обновление-все будет иметь повышенную тенденцию приводить к несовместимым средам. Я не знаю, может быть, нам стоит просто пойти дальше и реализовать команду upgrade-all даже зная, что она будет несовершенной с самого начала ... идеальное - враг хорошего и все такое. Может быть, мы могли бы попробовать обновить все, а затем автоматически запустить новый код pip check чтобы предупредить людей, если что-то сломалось, и им, возможно, придется исправить.

"проблема с кучей"

Да, отчасти это связано с тем, что такие пакеты, как numpy, дороги в установке или имеют тенденцию просто выводить ошибки (подумайте: пользователи Windows без компилятора). Для самого numpy эта проблема значительно уменьшена теперь, когда у нас лучшая поддержка колес, но есть много пакетов, помимо numpy, которым нужен компилятор. Чрезвычайно неприятно, когда вы просто пытаетесь обновить какой-то тривиальный пакет на чистом питоне, а затем внезапно Unable to find vcvarsall.bat .

И отчасти дело в том, что у людей привередливые предпочтения к таким вещам, как numpy. Например, часто смешивают патчи numpy-with-proprietary-MKL, установленные из Anaconda, при использовании pip для других пакетов, которые Anaconda не поставляет. И тогда pip install -U other-package может выбросить Anaconda numpy и заменить его на PyPI numpy, который дает вам numpy-сборку, которую вы не хотите + полностью нарушает вашу среду conda в будущем, потому что этот основной пакет только что получил удалил из-под конды.

И отчасти дело в том, что numpy является каноническим примером пакета, от которого сложным образом зависит _lot_ других пакетов, поэтому существует большой риск того, что попытка обновить пакет A -> вызовет обновление numpy -> сломает пакет B или C или D или ... Рекурсивные обновления создают удивительные связи между различными пакетами.

Чрезвычайно неприятно, когда вы просто пытаетесь обновить некоторые
тривиальный пакет pure-python, а затем внезапно не удается найти vcvarsall.bat
.

Именно это. Вы можете обойти это с помощью --no-deps или
--only-binary , но он делает то, что должно быть очень простым действием
во что-то действительно раздражающее. По моему опыту, единственный способ сохранить
среда должна тщательно настраивать трудно устанавливаемые пакеты
вручную, поддерживайте их вручную, а затем не позволяйте пипу обновлять их
автоматически. Эта последняя часть не так легко возможна с текущим
поведение --upgrade .

Для примера, отличного от numpy, lxml нелегко построить в Windows,
не поставляет колеса и зависит от многих вещей. Новый
выпуск lxml (до которого я, вероятно, не хочу беспокоиться об обновлении,
так как мне нужно вручную загрузить колесо Кристофа Гольке, когда он строит
его, и установить его вручную) может привести к обновлению всевозможных вещей до
неудача. Нежелательные обновления решат для меня эту проблему.

а затем не позволяйте pip обновлять их автоматически.

Я полагаю, что правильным решением для этого было бы закрепление версий, которые отслеживает https://github.com/pypa/pip/issues/654 , а затем выдача предупреждения, если закрепленная версия вызывает невыполнение требования dep. Это позволит пользователям _ действительно_ управлять пакетом вручную.

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

pip используется в 3 разных контекстах IME:

  • поддержание производственной среды
  • создание свежей среды воспроизводимым способом - например, сборка контейнеров
  • тестирование

@rbtcollins Мне непонятно, включает ли ваше определение «производственной среды» все, от «нового пользователя, который установил Python + некоторые пакеты» до «опытных пользователей с несколькими venvs» до «производственных развертываний, запускающих приложения / веб-сайты»? Ваши комментарии о безопасности кажутся такими, как будто вы больше всего беспокоитесь о последней категории, но, по-моему, это наименее интересная, потому что она обслуживает самых знающих пользователей. Значения по умолчанию следует выбирать для пользователей, не являющихся экспертами, тех, кто установил Python на свой ноутбук / настольный компьютер и хочет, чтобы их анализ был выполнен или веб-сайт заработал.

Я хотел бы снова оживить этот вопрос и связанные с ним обсуждения?

@rbtcollins Были ли

В обсуждении distutils-sig было как минимум 2 человека, которые были против самой идеи, что pip install выполняет обновление. Я по-прежнему готов принять консенсус сообщества, но меня не устраивает эта идея на чисто личном уровне. На самом деле мне не кажется, что мы близки к консенсусу, что простой pip install foo должен обновлять уже установленный foo .

Я не уверен, что здесь есть консенсус. Скорее два варианта использования, требующие разного поведения. Или, может быть, три:

  1. Автоматический сценарий (или пользователь, который не хочет проверять вручную), который хочет «убедиться, что foo доступен», но не хочет вносить ненужные изменения в систему. Идемпотентная установка.
  2. Пользователь, которому нужна последняя версия foo. Установить или обновить.
  3. Автоматизированный скрипт, который хочет убедиться, что foo (если он есть) обновлен. Обновление без установки.

Все это кажется допустимыми вариантами использования. Все может быть реализовано с точки зрения других с помощью достаточных ручных проверок или дополнительных сценариев. В настоящее время у нас есть (1) и (2) через install и install -U (по крайней мере, в простом случае - пока я намеренно игнорирую рекурсивное обновление).

Некоторые люди утверждают, что поведение по умолчанию install заставляет пользователей совершать ошибки, потому что они ожидают или нуждаются в поведении (2) и не понимают, что получают (1). Может быть, это так - мой опыт слишком ограничен, чтобы утверждать, что они ошибаются. Наши значения по умолчанию могут быть неправильными.

Рассмотрим практические аспекты (фундаментального вопроса «следует ли устанавливать обновление по умолчанию?»):

  1. Нет единого мнения о том, как простая установка должна соответствовать уже существующим требованиям. Но всегда требовать опцию - это плохой пользовательский интерфейс, поэтому нам нужно решить.
  2. Ничего не делать при наличии требования сводит к минимуму вероятность неожиданного изменения в системе пользователя. И обратите внимание, что откат такого неожиданного изменения нетривиален.
  3. Ничего не делать при наличии требования - это текущее поведение, поэтому его преимущество заключается в том, что не нарушаются пользовательские сценарии или существующая документация.
  4. Типичное английское использование слова «install» не включает в себя значение «upgrade». Если вы заменяете что-то более поздней версией, вы обычно говорите, что вы «обновили» это, а не что вы «установили» это.

Аргументы в пользу изменений выглядят так:

  • Это побуждает людей думать, что они обновлены, в то время как у них работает устаревшее программное обеспечение (плохое из-за ошибок и, возможно, дыр в безопасности). Наверняка это просто случай, когда люди не понимают, что делает команда, которую они запускают?
  • Он упускает возможность держать людей в курсе. Но должна ли это делать команда установки? Разве для этого не лучше использовать команду «обновить все мои вещи»? Аргумент здесь, кажется, состоит в том, что мы должны защищать людей от самих себя и делать обновления, которые они явно не запрашивали.
  • Текущее поведение ломает системы. На это сложно ответить без конкретики. Если pip install foo как способ получить foo нарушает работу системы пользователя, это ошибка - и плохая. Но более вероятно, что это ошибка в коде управления зависимостями, чем потому, что pip install foo не обновил уже установленный foo. Или ошибка документации (путая «как установить в первый раз» с «как обновить с предыдущей версии»), но это не «сломанная», просто сбивающая с толку.
  • Это соответствует поведению других систем. Дебаты по distutils-sig, кажется, указывают на то, что это далеко не так однозначно, как казалось при первом заявлении.

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

Личное мнение - нет ничего плохого в традиционных вариантах install и install --upgrade . Мне они кажутся ясными и естественными (повторюсь: в простых случаях). Нет опции «обновить, но только если она уже есть», но естественным местом для этого была бы новая команда upgrade , и я не думаю, что потребность в ней достаточно высока, чтобы гарантировать новую подкоманду, поэтому я m Нормально с тем, что придется заниматься этим делом вручную.

Неправильно изменять поведение «pip install». Нет ничего плохого в установке, означающей «убедитесь, что она установлена», и нет ничего плохого в установке, означающей «заменить указанный пакет последней версией», и разработчики достаточно умны, чтобы убедить себя, что любое поведение более интуитивно понятно. Но неправильно красть послеобеденное время у тысяч разработчиков, которые полагаются на текущее поведение и у которых внезапно возникнут проблемы со средой в следующий раз, когда они будут достаточно глупы, чтобы обновить pip.

Мне не понравилось предложение об изменении способа установки зависимости с прямым именем, но мне понравились остальные предложенные изменения, касающиеся рекурсивности обновлений пакетов, которые действительно происходят, и так далее.

Как раз сегодня кто-то попросил меня о помощи, потому что они были сбиты с толку, почему pip install --pre docker-py не установил 1.9.0rc2, а pip install docker-py==1.9.0rc2 установил. Они считали, что это ошибка в pip, пока не выяснилось, что причина в том, что у них уже была установлена ​​предыдущая версия docker-py и она использовалась.

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

@dholth говорит, что неправильно красть послеобеденное время тысяч разработчиков, полагающихся на текущее поведение, но что делать после обеда, когда тысячи разработчиков страдают от этого поведения? Как всегда, любая поломка - это всегда оценка стоимости поломки и преимуществ. Это делает поведение pip менее удивительным по умолчанию, вам не нужно проверять среду, чтобы выяснить, каким будет результат какой-либо команды, вам нужно только знать команду.

Я думаю, что какое бы решение ни было выбрано, нам нужно будет предоставить возможность включить старое поведение, чтобы сгладить переход.
Если мы пойдем с обновлением pip install foo нам понадобится --no-upgrade .
Если мы удалим рекурсивное поведение обновления, нам понадобится --recursive .

Я точно согласен с флагом --no-upgrade (и сохраняю флаг --upgrade чтобы его можно было вернуть к обновлению, если кто-то отключил его). Я не уверен в долгосрочном использовании флага --recursive , но я не категорически против этого.

Я думаю, что это изменение приведет к серьезным сбоям, но в основном при неинтерактивных вызовах pip, в то время как pip install -U - это то, что обычно происходит в интерактивном режиме и, что особенно важно, когда кто-то занимается разработкой и доступен для решения последствия. Вот почему я в шутку предложил, чтобы мы могли проверить isatty (), чтобы выбирать между тем или иным поведением. Но есть ли способ измерить количество времени или это просто круговорот мнений? Мое мнение таково, что, как опытный человек, мне нужно повторно набирать install с -U, но это быстро, в то время как исправление virtualenv, когда я меньше всего ожидал, происходит в сотни раз медленнее.

Другое решение, которое уже обсуждалось, - дать новому поведению новое имя (имя, которое легче запомнить, чем pip install -U?), И обучить людей новой лучшей практике; если новички, у которых теоретически больше всего проблем, читают новую документацию и используют новое имя, проблема решена.

Кстати, а где же команда pip rollback? До и после каждого вызова pip должен сохранять версии и, возможно, колеса каждого установленного пакета в журнале вместе с меткой времени. Тогда, если есть проблема, вы можете просто вернуться назад, без суеты.

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

Тот факт, что поломка будет в основном в неинтерактивных вызовах pip, на самом деле хороший момент, но я думаю, что больше к тому факту, что мы должны это сделать. Основное место, где текущее поведение имеет смысл, - это сценарий с использованием pip, и когда вы пишете сценарий, добавление дополнительного флага к команде не является большим бременем, однако, когда вы запускаете pip в интерактивном режиме, параметром по умолчанию должна быть опция, которая вы, скорее всего, захотите.

Если вам нужна команда отката, я предлагаю для нее другую проблему.

Что касается байкешеддинга пользовательского интерфейса, мне все еще нравится идея о том, что идемпотентное / ориентированное на сценарии поведение получает новый глагол, например pip require numpy - для меня это хорошо помогает уловить концептуальную разницу (в то время как pip's чаще of flags очень сбивает с толку, а их взаимодействие трудно предсказать), и при написании сценария IME легче запомнить глагол, который означает то, что вы хотите, чем не забывать постоянно передавать какой-то дополнительный флаг каждый раз.

Но я думаю, что глагол, которому мы сначала обучаем пользователей (это install ), должен быть глаголом, значения по умолчанию которого ориентированы на новые потребности пользователей, что означает интерактивное использование, интерпретируя pip install django как значение pip install django==$LATEST и т. д.

Но есть ли способ измерить количество времени или это просто круговорот мнений?

Это как раз моя точка зрения. Я не думаю, что есть какие-либо убедительные (например, способные убедить другой лагерь) аргументы для какой-либо из сторон. И в этом случае статус-кво побеждает. Меня больше всего беспокоит то, что у нас (как у проекта) нет хороших средств для разрешения такого рода ситуаций, и в конечном итоге это нависает над нами навсегда, потому что всегда есть вероятность, что кто-то может совершить пиар, просто потому что те, кто возражал в прошлый раз, не заметили возобновления обсуждения. Нам нужен какой-то эквивалент отклоненных PEP Python, который позволил бы нам сказать «мы решили (по следующим причинам) ничего не делать», а затем иметь возможность сократить процесс, когда кто-то просит пересмотреть решение и придется снова пройти через все старые бесплодные споры.

Я бы предпочел найти способ сделать текущее нестандартное поведение более доступным для людей, которые в нем нуждаются, чем тратить время на споры, которые просто приведут к тому, что обе стороны будут все более и более закрепляться на своих позициях. Хотя я действительно не знаю, как это сделать - я действительно не понимаю, что такого сбивает с толку в " install installs, install --upgrade installs, но также при необходимости обновлениях".

Но я думаю, что глагол, который мы сначала учим пользователей (то есть установить), должен быть глаголом, значения по умолчанию которого ориентированы на новые потребности пользователей, что означает интерактивное использование, интерпретацию pip install django как значение pip install django == $ LATEST и т. Д.

Что ж, хотя я понимаю вашу точку зрения, что мы должны рассматривать интерактивное использование (новыми пользователями) как основной вариант использования, я не уверен, что это подразумевает «установку или обновление». Я бы сказал, что режим отказа подразумеваемого обновления (вы обновляете существующую установку, не желая этого, и тем самым нарушая другую часть вашей системы) достаточно плох (даже для опытного пользователя), что требует наличия флага «Я понимаю последствия».

Инструкции проекта, в которых говорится «используйте pip install FOO и все готово», можно (и нужно) изменить. Мы не должны принимать подобное решение на основе ошибочной документации других людей, независимо от того, сколько ее там есть. Формулировка должна быть простой: «Если у вас еще нет FOO, используйте pip install FOO и все готово. Если у вас уже есть FOO, но вы хотите новую версию, используйте pip install --upgrade FOO ».

Я знаю, что есть анекдотические свидетельства того, что люди тратили много времени, пытаясь понять, что пошло не так, потому что они не включили --upgrade . Но как мы должны это оценить, учитывая, что (по определению) невозможно получить свидетельство того, сколько людей _не_ не имеют проблем с текущим поведением? Внесите изменения и дождитесь сообщений об ошибках от людей, которые говорят: «Я сделал pip install foo и он обновил мой существующий foo, который сломал bar - как мне распаковать этот беспорядок?» Лично я не хочу поддерживать людей в такой ситуации ...

Mercurial измеряет статистику использования с Facebook, у них есть специальный корпоративный плагин для ее записи.

Я действительно не понимаю, что сбивает с толку в «установить устанавливает, устанавливает --upgrade устанавливает, но и при необходимости обновляет».

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

У меня на моем персональном компьютере всегда есть что-то вроде 50-100 различных виртуальных сред, по одной для каждого проекта, над которым я работаю. Для меня практически невозможно узнать, что установлено в конкретной среде, не сидя там и не нажимая pip list а затем просматривая весь список, что отнимает намного больше времени, чем я когда-либо собирался делать.

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

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

Но как мы должны это оценить, учитывая, что (по определению) невозможно получить доказательства того, сколько людей не испытывали никаких проблем с текущим поведением?

Метрики в OSS - это проблема :( В какой-то момент было бы здорово, если бы мы могли получить некоторые, чтобы мы могли видеть такие вещи, как «этот человек запускал установку, а затем ничего больше» по сравнению с «этот человек запускал установку, а затем почти сразу же повторно» запустил его с помощью --upgrade ". К сожалению, он все еще находится в фазе" ну, было бы неплохо "и еще близко не закончен, поэтому нам остается бросать куриные кости и пытаться угадать реальность из воображения.

поведение по умолчанию требует, чтобы вы знали, что уже установлено в вашей системе

Хотя я понимаю, что это может быть проблемой, я не совсем уверен, что это серьезная проблема. В конце концов, если вы сделаете pip install и пакет уже присутствует, вы сразу получите ответ:

(x) C:\Work\Scratch>pip install wheel
Requirement already satisfied (use --upgrade to upgrade): wheel in c:\work\scratch\x\lib\site-packages

Так что не похоже, что вам понадобится вечность, чтобы узнать, что вам нужно обновить, или как это сделать.

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

Чем больше мы обсуждаем это, тем меньше я понимаю преимущества обновления по умолчанию.

В конце концов, если вы сделаете pip install и пакет уже присутствует, вы получите немедленную обратную связь.

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

$ pip install Pyramid
Collecting Pyramid
  Using cached pyramid-1.7-py2.py3-none-any.whl
Collecting WebOb>=1.3.1 (from Pyramid)
  Using cached WebOb-1.6.1-py2.py3-none-any.whl
Collecting translationstring>=0.4 (from Pyramid)
  Using cached translationstring-1.3-py2.py3-none-any.whl
Collecting zope.deprecation>=3.5.0 (from Pyramid)
Collecting venusian>=1.0a3 (from Pyramid)
Requirement already satisfied (use --upgrade to upgrade): setuptools in ./lib/python3.5/site-packages (from Pyramid)
Collecting PasteDeploy>=1.5.0 (from Pyramid)
  Using cached PasteDeploy-1.5.2-py2.py3-none-any.whl
Collecting repoze.lru>=0.4 (from Pyramid)
Requirement already satisfied (use --upgrade to upgrade): zope.interface>=3.8.0 in ./lib/python3.5/site-packages (from Pyramid)
Installing collected packages: WebOb, translationstring, zope.deprecation, venusian, PasteDeploy, repoze.lru, Pyramid
Successfully installed PasteDeploy-1.5.2 Pyramid-1.7 WebOb-1.6.1 repoze.lru-0.6 translationstring-1.3 venusian-1.0 zope.deprecation-4.1.2

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

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

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

Хороший момент, возможно, его следует выделить (мы используем цвета для таких вещей, как предупреждения, это кажется хорошим кандидатом).

Видите ли, я не думаю, что обновление по умолчанию вообще небезопасно

Что ж, предположим, что у вас установлен foo 1.0 и bar 1.0, который зависит от foo. Предположим, что bar работает с foo 1.0, но не с foo 2.0 (но зависимость только от «foo», а не от «foo <2.0», потому что foo 2.0 не отсутствовал, когда был выпущен bar 1.0, и откуда автору знать?) если я сделаю pip install --upgrade foo , бар сломается. И я могу даже не узнать, что планка сломана в течение долгого времени, если это не то, чем я часто пользуюсь. Это не режим отказа, с которым я хочу иметь дело как с поведением по умолчанию - даже если он редко, и даже если это, возможно, вина bar за то, что он не более строг в своих зависимостях.

Я не хочу превращать это в упражнение «мой сценарий неудачи хуже, чем ваш», так как это имеет тенденцию делать дискуссию слишком жаркой (см. Типичное обсуждение безопасности), но я действительно думаю, что «совсем не небезопасно» неверно - в лучшем случае это «вряд ли вызовет проблемы».

Конечно, вы упомянули здесь «другое изменение для обновления». Предлагается слишком много комбинаций вещей, которые становятся зависимыми друг от друга (обновление, обновление всего, откат, рекурсивное обновление, отсутствие желания обновления и т. Д.). Может быть, нам следует делать что-то пошагово - почему бы не оставить это обсуждение и сосредоточиться на «безопасном обновлении». Как только у нас будет pip install --upgrade в месте, где мы можем гарантировать, что он никогда не сломает чью-то систему, может быть, тогда мы сможем возобновить дискуссию о поведении по умолчанию?

Я не хочу превращать это в упражнение «мой сценарий неудачи хуже, чем ваш».

Точно! Давай не будем.

Предлагается слишком много комбинаций вещей, которые становятся зависимыми друг от друга (обновление, обновление всего, откат, рекурсивное обновление, отсутствие желания обновления и т. Д.). Может быть, нам следует делать что-то пошагово - почему бы не оставить это обсуждение и сосредоточиться на «безопасном обновлении».

«Другое изменение» - это переход к нежелательным обновлениям. Я считаю, что эта проблема касается только изменения поведения install и install --upgrade и, следовательно, должна включать обсуждение стратегий обновления. Все остальное (обновление, откат) мы явно развязали, когда открыли эту проблему.

Как только у нас будет pip install --upgrade в месте, где мы можем гарантировать, что он никогда не сломает чью-то систему, может быть, тогда мы сможем возобновить дискуссию о поведении по умолчанию?

Это означало бы сначала решить # 988, который застрял в течение довольно долгого времени.


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


При желании уже можно делать обновления без особого энтузиазма, но для того, чтобы понять это, потребуется поиск в Google, что сложнее, чем следовало бы. Даже если pip предоставляет возможность при установке выполнять неактивные обновления, это будет лучше, чем статус-кво.

Кроме того, я не думаю, что кто-то хочет, чтобы текущее значение по умолчанию для «нетерпеливого обновления» использовалось по умолчанию. Если это не так, я, должно быть, пропустил это. Так почему бы по умолчанию не переключиться на неактивные обновления? Пока мы переключаем стратегию обновления по умолчанию, чтобы она была неактивной, и _могут_ предоставить способ выполнять активные обновления, мы будем лучше, чем статус-кво.

Итак, если предположить, что никто не возражает против этих двух пунктов, минимальное нарушение будет следующим:

  • pip install --upgrade по умолчанию предоставляет нежелательные обновления.
  • Добавьте --upgrade-strategy=[eager/non-eager] (с любым написанием), чтобы выбрать стратегию обновления, если вы действительно хотите обеспечить быстрое обновление.

Как это звучит?

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

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

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

Просто чтобы уточнить - я не верю, что нежелательные обновления решат проблему, заключающуюся в том, что "pip install --upgrade foo" может обновить foo с 1.0 до 2.0, но уже установленная панель может объявить зависимость от foo (без версии ) а с 2.0 не работает? Я не понимаю, что это возможно (или действительно должно), и все же именно такой сценарий беспокоит меня, когда я делаю обновление по умолчанию.

Это не означает, что у меня проблемы с вашим предложением получить в качестве первого шага нежелательные обновления (в любом случае я +1).

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

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

Никто не запускает pip install foo когда они уже _знают_, что foo установлен, потому что это было бы глупо. Таким образом, пользователи уже должны быть готовы к тому, что это может нарушить их среду, потому что установка новых пакетов (и извлечение их произвольных транзитивных зависимостей) так же опасна, как и обновление существующих пакетов. Фактически, обновление foo и установка foo _ точно_ так же опасно, потому что они делают _ в точности то же самое_ - они используют одни и те же версии одних и тех же пакетов.

Аргумент, что простой pip install numpy должен интерпретироваться как pip install numpy==$LATEST состоит в том, что это намного проще и предсказуемо, чем текущее (где pip install numpy интерпретируется как pip install numpy==$CURRENTLY_INSTALLED_VERSION если в настоящее время нет установленной версии, и в этом случае она интерпретируется как pip install numpy==$LATEST - просто посмотрите, сколько времени ушло на запись). Это уменьшает пространство состояний, которое пользователь должен отслеживать - я не вижу, как сокращение возможных результатов команды до строгого подмножества того, чем они были раньше, делает ее более опасной :-).

Это также имеет важное преимущество, которое на самом деле _ сокращает_ распространение путей через внутреннее устройство pip - наличие отдельных опций для каждой мелочи, независимо от того, насколько они используются (полные / менее), имеет очень существенные затраты для разработчиков и является тем, как pip стал "Машина печали Руба Голдберга", описанная в теме # pypa-dev.

Инструкции проекта, в которых говорится «используйте pip install FOO, и все готово», можно (и нужно) изменить.

Мне трудно поверить, что вы бы смирились с этим аргументом, если бы мы говорили о библиотечном API :-(. «Да, многие пользователи этой функции API вызывают ее со значениями по умолчанию, и да, они работают на 95% время, чтобы большинство пользователей не осознавали, что их код сломан в остальных 5% случаев. Решение состоит в том, чтобы сохранить этот API в том виде, в каком он есть, и постоянно хранить отчеты об ошибках, предлагая всем добавить unbreakme=True kwarg на каждый звонок. Потому что это полностью вина пользователя ".

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

Однако это работает не так - обратите внимание, что это изменение широко обсуждалось на github, а затем был заголовок списка рассылки, чтобы никого не удивить.

На самом деле мне хотелось бы, чтобы это работало именно так, потому что это изменение было бы _fait donei_, и мы все могли бы двигаться дальше и перестать тратить на это время ;-). И шутки в сторону, на самом деле для проекта могло бы быть лучше, если бы кто-то вроде dstufft решил поиграть в BDFL в подобных ситуациях. Прямо сейчас де-факто результат состоит в том, что изменения просто невозможны, и я начинаю чувствовать, что было бы более продуктивно отказаться от попыток улучшить пипс и вместо этого направить свою энергию / рекомендовать другим вложить свою энергию в выяснение того, как сделать жизнеспособную вилку для пипса :-(

Просто чтобы уточнить - я не верю, что нежелательные обновления решат проблему, заключающуюся в том, что "pip install --upgrade foo" может обновить foo с 1.0 до 2.0, но уже установленная панель может объявить зависимость от foo (без версии ) а с 2.0 не работает?

FWIW, я не думаю, что это работает, даже если bar явно зависит от foo == 1.0.

/tmp/pip-testing
$ ls ./repo
bar-1.0.tar.gz  foo-1.0.tar.gz  foo-2.0.tar.gz

/tmp/pip-testing
$ pip install --find-links ./

/tmp/pip-testing
$ pip install --find-links ./repo bar
Collecting bar
Collecting foo==1.0 (from bar)
Building wheels for collected packages: bar, foo
  Running setup.py bdist_wheel for bar ... done
  Stored in directory: /home/pradyunsg/.cache/pip/wheels/20/cd/44/f59790040978a7eb9989ce680e85681c252516bd7fc9baf059
  Running setup.py bdist_wheel for foo ... done
  Stored in directory: /home/pradyunsg/.cache/pip/wheels/27/9a/5f/3e8efff98718d38adb7cf6b20e4435694e8c465085792441be
Successfully built bar foo
Installing collected packages: foo, bar
Successfully installed bar-1.0 foo-1.0

/tmp/pip-testing
$ pip install --upgrade foo
Requirement already up-to-date: foo in /home/pradyunsg/.venvwrap/venvs/tmp-734de48113851ca/lib/python3.5/site-packages

/tmp/pip-testing
$ pip install --find-links ./repo --upgrade foo
Collecting foo
Building wheels for collected packages: foo
  Running setup.py bdist_wheel for foo ... done
  Stored in directory: /home/pradyunsg/.cache/pip/wheels/9d/3e/ce/b183a52b3e6844394d6cbf5606acadf8c340d48ccfcf02cc1c
Successfully built foo
Installing collected packages: foo
  Found existing installation: foo 1.0
    Uninstalling foo-1.0:
      Successfully uninstalled foo-1.0
Successfully installed foo-2.0

/tmp/pip-testing
$ pip list
bar (1.0)
foo (2.0)
pip (8.1.2)
setuptools (25.0.0)
wheel (0.29.0)

/tmp/pip-testing
$ pip --version
pip 8.1.2 from /home/pradyunsg/.venvwrap/venvs/tmp-734de48113851ca/lib/python3.5/site-packages (python 3.5)

Я не думаю, что это работает, даже если bar явно зависит от foo == 1.0.

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

OTOH. В случае, когда bar использует неверсионную зависимость от foo, в принципе невозможно получить правильный AFAICT, поэтому я не уверен, что это имеет отношение к чему-либо. Единственное решение для этого - «никогда больше не трогать свой venv», и даже это не гарантируется (из-за таких вещей, как новые дыры в безопасности или изменения во внешних API, с которыми вам нужно поговорить).

Фактически, обновление foo и установка foo столь же опасны, потому что они делают одно и то же - они используют одни и те же версии одних и тех же пакетов.

OK. Мы действительно просто собираемся согласиться не соглашаться по этому поводу. На мой взгляд, все дело в восприятии пользователя - «установка foo» - это _добавление чего-то, чего раньше не было_ в вашу систему, тогда как «обновление foo» _изменяет то, что уже есть_. Для пользователя это далеко не одно и то же.

Сейчас де-факто результат таков, что изменения просто невозможны.

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

Я выхожу из этого обсуждения сейчас. Если кто-то выдвигает аргумент, который изменяет мое мнение, я признаю это, но в остальном мне больше нечего сказать. Если я последний, кто возражает против этого изменения, я разрешаю всем игнорировать меня - я определенно не считаю, что у меня (или у кого-либо) должно быть право вето на изменения, и мне вполне комфортно принимать решение большинства. Если у других все еще есть сомнения по поводу этого изменения, им придется выдвигать свои собственные аргументы (но я хотел бы напомнить участникам, что не все читают проблемы с github - несмотря на то, что обсуждение идет не по плану, были некоторые комментарии по distutils- сиг, что ИМО заслуживает ответа).

И шутки в сторону, на самом деле для проекта могло бы быть лучше, если бы кто-то вроде dstufft решил поиграть в BDFL в подобных ситуациях. Сейчас де-факто результат таков, что изменения просто невозможны.

Хотя я не считаю наш текущий процесс оптимальным, я не думаю, что он настолько плох, как «изменения невозможны». Как правило, раньше мы делали что-то вроде поднять что-нибудь на pypa-dev ML простым большинством голосов среди ядра pip в случаях, когда не было четкого консенсуса. Я думаю, что сейчас есть три активных разработчика ядра pip (Myself, @pfmoore и @xavfernandez), поэтому, если все трое из нас проголосуют, вы так или иначе получите голос вместо ничьей. Можно ли использовать более формализованный процесс? Да, возможно. Может быть, это роль BDFL? Возможно, но я не думаю, что это необходимо.

К сожалению, текущий специальный процесс обычно означает, что один из основных участников должен сесть и решить продвинуть изменение, сказать «Хорошо, давайте проголосуем за это» и объявить некоторые специальные правила для этого.

Напомним, было достигнуто соглашение об изменении поведения --upgrade , что является основным препятствием для таких вещей, как проекты, зависящие от Numpy, в объявлении своей зависимости. Это конкретное изменение - просто идея, которая возникла в результате этого, и больше относится к UX, чем к чему-либо еще. Как и в любом другом проекте, если вы не являетесь BDFL, будут моменты, когда процесс принятия решений идет вразрез с тем вариантом, который вам нужен. Я не делал ничего из этого, потому что в последнее время я сосредоточился на Warehouse, пип вернется в моем прицеле после того, как он будет запущен :)

Никто не запускает pip install foo, когда уже знает, что foo установлен, потому что это было бы глупо.

Я предполагаю, что вы правы, но я бы также сказал, что многие люди используют pip install -r requirements.txt с requirements.txt содержащим foo (что эквивалентно pip install foo ), даже если они знают, что foo устанавливается ежедневно.
И они довольны тем, что pip делает это быстро, не проверяя, есть ли что-то для обновления.

Я не против того, что pip install foo может быть эквивалентно pip install foo==$LATEST (на самом деле мне это нравится), но я против изменения этого фундаментального поведения без периода устаревания (и возможности выхода на сохранить старое поведение).
Я не уверен, что мы уже обсуждали это решение, но это может быть новый вариант --strategy для pip install :

  • no-upgrade будет значением по умолчанию в пункте 9, а pip install --strategy=no-upgrade будет текущим поведением pip install
  • eager будет текущим поведением pip install --upgrade--upgrade устаревшим псевдонимом для --strategy=eager )
  • non-eager будет значением по умолчанию в пункте 10
  • мы могли бы представить oldest-compatible для # 3188 и т. д.

Обратите внимание, что вы также можете поместить strategy=non-eager в свой pip.conf, чтобы напрямую использовать его по умолчанию в pip 9.

Можно ли использовать более формализованный процесс? Да, возможно.

: +1:

И они довольны тем, что pip делает это быстро, не проверяя, есть ли что-то для обновления.

Вероятно, это все равно будет довольно быстро. Мы обслуживаем ответы менее чем за миллисекунду из кеша Fastly :)

Я не против того, чтобы pip install foo мог быть эквивалентен pip install foo == $ LATEST (на самом деле мне это нравится), но я против изменения этого фундаментального поведения без периода устаревания (и возможности выхода, чтобы сохранить старое поведение).

Меня устраивает срок устаревания. Я не уверен в долгосрочном варианте сохранения прежнего поведения. Я не против, я просто хочу убедиться, что это то, что мы действительно должны поддерживать в долгосрочной перспективе, варианты в целом имеют свою стоимость, и я хочу убедиться, что цена того стоит.

Как это звучит?

Далее следует # 3972.

Закрытие с # 3972 объединено.

Мы пошли другим путем к разрешению поведения --upgrade .

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

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