Pip: Новый Resolver: развертывание, циклы обратной связи и процесс разработки

Созданный на 25 мая 2019  ·  83Комментарии  ·  Источник: pypa/pip

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

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


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

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

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

С точки зрения git/GitHub, это, вероятно, первая «экспериментальная» реализация функции в pip. FWIW, я планирую проводить эксперименты и т. Д. На своем форке и регулярно объединять прогресс с основным репозиторием pip (исключительно код в pip._internal.resolution). Я не хочу шуметь в основном репозитории, но я хочу синхронизировать master с работой над этим.


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

dependency resolution maintenance

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

Я молод, глуп и оптимистичен

:-) А я иногда бываю слишком стар, устал и циничен. Давайте продолжим вашу философию, она звучит намного лучше :-)

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

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

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

Это потребует CTA для пользователей, чтобы попросить их попробовать и оставить отзыв.

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

Мое личное мнение таково, что «сделать это доступным и запросить отзыв» — это интересный вариант того, что мы пробовали ранее, но в конечном итоге это не будет иметь большого значения. Слишком много людей используют последний pip с параметрами по умолчанию в своих автоматизированных конвейерах сборки и не тестируют перед переходом на новую версию pip (мы видели это с PEP 517).

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

С точки зрения git/GitHub, это, вероятно, первая «экспериментальная» реализация функции в pip.

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

Я потратил ~ 60 минут (ре-ре-ре-ре-) на написание этого поста, так что теперь я пойду смотреть места в Нью-Йорке! Если вы не видите быстрого ответа от меня, это потому, что я буду в туристическом режиме.


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

Определенно! Это 80% причин, по которым я ставлю #5051 впереди этого — я намерен погасить большую часть технического долга, который мы накопили в нашей логике сборки, чтобы его стало легче повторно использовать (все?). Куча кода должна быть :fire: и я согласен, что остальная часть определенно должна быть повторно использована настолько, насколько это разумно.

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

Да, действительно. Я также намекаю на поток разработки здесь - IMO было бы нормально объединить пустую инфраструктуру (классы с кучей методов, которые просто raise NotImplementedError() , которые будут конкретизированы в последующих PR), или нет. охватывает все случаи (неполная реализация) в ветку master , если она используется только после флага, который явно отмечен как «экспериментальный/альфа».

Re: обратная связь

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

Глядя на наши недавние «основные» изменения, я думаю, что большая часть отзывов, которые мы получили, была реактивной — от пользователей, осознавших проблемы с их рабочими процессами, когда они сломались, а затем обратившихся к нам, чтобы сообщить об этом. У многих из них, возможно, не было времени, чтобы помочь сгладить детали новой функциональности, что вызывает много трений. Это также стоило нам большого количества нашего «бюджета на отток» [1], который я не хочу тратить больше, так как Python Packaging в любом случае не так уж много осталось [2].

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

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

Re: гранты

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

FWIW, у PSF есть действующий контракт на помощь в установлении связи, связанной с PyPA/Packaging, с Changeset Consulting, так что, может быть, мы можем использовать это?


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

Сноски:

  1. Очень хороший термин, который использовал @pganssle, и я обязательно буду его использовать.
  2. Вот почему я отложил #3164 на второй план, несмотря на предложенную там реализацию пакета "pip-cli" и разумный консенсус относительно того, как мы хотим, чтобы развертывание выглядело.

Я молод, глуп и оптимистичен

:-) А я иногда бываю слишком стар, устал и циничен. Давайте продолжим вашу философию, она звучит намного лучше :-)

Определенно! Это 80% причин, по которым я ставлю #5051 впереди этого — я намерен погасить большую часть технического долга, который мы накопили в нашей логике сборки, чтобы его стало легче повторно использовать (все?).

Здорово!

Только что из IRC :

[sumanah] pradyunsg: Можем ли мы, сообщество pip & Packaging, сделать что-нибудь, чтобы помочь вам быстрее выполнять больше работы с преобразователем?
....
[pradyunsg] На самом деле, прямо сейчас информация на https://github.com/pypa/pip/issues/6536 , вероятно, помогла бы мне понять, как подходить к работе / получать отзывы от людей и т. д.
....
[sumanah] pradyunsg: re: Новый Resolver: развертывание, циклы обратной связи и поток разработки #6536 -- вы хотите ввести что-то вроде: является ли подход с флагом функции хорошей идеей? Это хорошая идея, чтобы получить обратную связь через какой-либо механизм, отличный от проблем GitHub pip? Это хорошая идея, чтобы получить грант или что-то подобное, чтобы создать реальное ручное тестирование и надежную инфраструктуру тестирования и / или проактивную связь?
...
[pradyunsg] Да, хороши ли идеи, которые я предлагаю. Кроме того, любые дополнительные идеи/подходы/мысли, которые могут помочь более плавному развертыванию + обратная связь, были бы замечательными.

Так:

Является ли подход с флагом функции хорошей идеей? да.

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

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

Может ли Changeset (я) в соответствии с существующим контрактом с PSF на помощь в координации/коммуникациях PyPA, помочь pip с упреждающими коммуникациями, чтобы обеспечить нам более систематическое ручное тестирование в реальных условиях? Предполагая, что у меня осталось несколько часов по контракту к тому времени, когда мы хотим начать это развертывание, да.

Это хорошая идея, чтобы получить грант или что-то подобное, чтобы получить больше помощи с пользовательским интерфейсом, общением/рекламой и тестированием? да. Потенциально могут представлять интерес гранты PSF , а также гранты NLNet (для запросов на сумму менее 30 000 евро ), потенциально необходимое программное обеспечение с открытым исходным кодом Чана Цукерберга для научного гранта и MOSS от Mozilla . WG по упаковке может быть зарегистрированным заявителем. Если @pradyunsg или @pfmoore хотят кивнуть "да, звучит интересно", я могу начать изучение этих возможностей с рабочей группой.

Если @pradyunsg или @pfmoore хотят кивнуть "да, звучит интересно",

Это определенно звучит интересно для меня :-)

@pradyunsg или @pfmoore хотят кивнуть "да, звучит интересно"

_nods_ да, звучит интересно

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

@brainwane Также здесь уместно https://github.com/pypa/integration-test. Я думаю, что установка этого — еще одна потенциальная область для финансирования — мы должны добавить это на https://wiki.python.org/psf/Fundable%20Packaging%20Improvements.

В ПОРЯДКЕ! Я начал разговаривать с PSF и с людьми из Инициативы Чана Цукерберга о подаче заявки на грант CZI через Рабочую группу по упаковке. Я добавил некоторые подробности на страницу «Улучшения упаковки для финансирования» о том, почему важен новый распознаватель пипсов, и добавил в этот список проект integration-test . И я начал собирать имена экспертов по пользовательскому опыту, которые могут исследовать нашу сложную цепочку инструментов для распространения/установки пакетов из командной строки, разговаривать с пользователями, чтобы понять их ментальную модель того, что происходит и что должно произойти. , и посоветуйте сопровождающим.

Если мы получим деньги в виде грантов от MOSS, CZI или NLNET, я думаю, мы получим деньги ... возможно, не раньше октября. Грант непосредственно от PSF , вероятно, был бы быстрее, но «наше текущее внимание сосредоточено на семинарах по Python, конференциях (особенно для финансовой помощи) и усилиях по разнообразию / инклюзивности Python».

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

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

Например, люди, пришедшие из javascript или rust, также ожидают какой-то файл блокировки, так что это может быть что-то, что нужно учитывать...

Извините, что вмешиваюсь, рад видеть, что это продвигается вперед!

Мое личное мнение таково, что «сделать это доступным и запросить отзыв» — это интересный вариант того, что мы пробовали ранее, но в конечном итоге это не будет иметь большого значения. Слишком много людей используют последний pip с параметрами по умолчанию в своих автоматизированных конвейерах сборки и не тестируют перед переходом на новую версию pip (мы видели это с PEP 517).

Как один из людей, которые столкнулись с некоторыми проблемами PEP 517 именно по этой причине, я действительно хотел бы увидеть способ добровольного тестирования. Но я знаю об этом только потому, что я подписался на все источники новостей об упаковке python, какие только мог, после проблемы с флагом --no-use-pep517 . Я хочу сказать, что распространять такого рода новости сложно, и, вероятно, поэтому трудно получить обратную связь.

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

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

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

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

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

В некотором смысле, разве это уже не существует в виде --pre ? Может ли канал бета-релиза для pip просто запустить pip install --upgrade --pre pip ?

Извините, что вмешиваюсь, рад видеть, что это продвигается вперед!

@techalchemy пожалуйста, из всех людей _вам_ определенно не нужно сожалеть о том, что вы вступаете в эту дискуссию.

Это то, что позволяют ресурсы, которые вы ищете?

В какой-то степени да.

рег: бета-релизы/"канал" для пункта

Спасибо за участие @jriddy и @chrish42. Хотя я думаю, что в целом это определенно полезный/важный разговор, я также чувствую, что это немного ОТ для этой проблемы. Тем не менее, я отвечу здесь один раз; если мы хотим обсудить это подробнее, давайте откроем новую тему.

Мы пробовали это в прошлом — совсем недавно с пунктом 10 — но это не сработало. Я немного скептически отношусь к тому, насколько хорошо это может работать в будущем, но я также могу предположить, что некоторые изменения в нашем процессе могут привести к тому, что он будет работать для нас гладко. Может быть, мы могли бы сделать «только бета-версию» набора функций или что-то в этом роде? Я представлял -X all как синтаксис для этого в #5727. Может быть, мы могли бы включить это в план развертывания? Я не знаю. Нам нужно будет потратить время и энергию, чтобы понять это. :)

Как упоминалось в https://github.com/pypa/packaging-problems/issues/25#issuecomment -520167480, я думаю, что важно иметь сводное объяснение того, как решатель меняет опыт работы с пунктами. Многие люди будут разочарованы переходом на более жесткую систему (хотя в целом все должно быть более надежным, они будут заблокированы в тех местах, где они в настоящее время не заблокированы).

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

Пререлиз — хорошая идея. В conda у нас есть пререлизный канал conda-canary. Мы рекомендуем людям настроить задание CI для работы с canary таким образом, чтобы помочь им увидеть, не сломают ли их изменения conda. В идеале они сообщают нам, прежде чем мы выпустим эту версию. Этот канал потерпел неудачу. Единственный раз, когда люди действительно используют его, это когда они хотят получить новейшую версию, чтобы исправить какую-то ошибку, с которой они борются. Мы не получаем много отчетов от предполагаемых первых последователей. Я по-прежнему думаю, что пререлиз — это хорошая идея, потому что, когда релиз идет плохо и люди злятся на вас за то, что вы сломали их 700 управляемых узлов, вы можете сказать: «Ну, он был доступен за неделю до того, как мы его выпустили. вы тестируете эти вещи перед тем, как развернуть их на 700 узлах?» Вы даете людям возможность заставить вещи работать лучше. Помогите им осознать, что отказ от этой возможности означает для них еще большую боль в будущем. Для них это стоящая инвестиция, и если они делают это как часть своего CI, им не нужно тратить время, кроме установки.

По поводу флага: я думаю, что лучше иметь параметр конфигурации (возможно, в дополнение к флагу). Я бы не хотел постоянно передавать флаг. Я не уверен, что у pip есть такая возможность — может быть, вы скажете людям, которым нужен более постоянный переключатель, использовать соответствующий env var?

По поводу флага:

параметры CLI pip автоматически сопоставляются с параметром файла конфигурации и переменной среды с соответствующими именами.

@msarahan Спасибо за участие, очень признателен! :)

Что касается параметра «позвольте мне делать то, что я хочу» для игнорирования сломанных зависимостей, я думаю, что было бы желательно структурировать флаг функции таким образом, чтобы он также мог служить в качестве отказа после того, как преобразователь включается по умолчанию (например, запуск с --avoid-conflicts в качестве подписки, в конечном итоге перейдите к --no-avoid-conflicts в качестве отказа, но примите оба варианта с самого начала)

Вы также захотите рассмотреть, как --ignore-installed взаимодействует с решателем — когда он будет передан, вам, вероятно, следует игнорировать все требования для уже установленных пакетов.

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

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

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

Однако, если есть варианты использования, которые эти два варианта не охватывают, мне бы очень хотелось узнать о них. :)


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

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

IDK, я использую эту «функцию», чтобы делать довольно сумасшедшие вещи со сборками, например...

# install just the packages I've built specifically
pip install --no-index --no-deps --find-links=/path/to/my/local/build/cache -r local-reqs.txt

# ...snip to later in a dockerfile, etc...

# install the deps from public PyPI
pip install -r local-reqs.txt

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

Но, возможно, поведение «наивного разрешения» все еще имеет смысл.

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

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

  1. Ошибка резолвера. Очевидная возможность, легко исправить — исправить ошибку в следующем выпуске pip.
  2. Случаи, когда старый преобразователь неверен (генерирует результаты, которые не удовлетворяют ограничениям). Мы не собираемся поддерживать это в будущем, верно? (По крайней мере, не с помощью чего-то менее экстремального, чем пользователь, закрепляющий то, что он хочет, и использующий --no-deps для отключения преобразователя).
  3. Случаи, когда старый и новый распознаватели дают разные результаты, оба из которых удовлетворяют заданным ограничениям. Пользователи могут добавлять ограничения, чтобы заставить старый результат (если они не могут, это возвращает нас к (2)). Мы должны дать им время, чтобы сделать это, но затем отказаться от старого преобразователя, как и любую другую устаревшую функциональность.
  4. Крайний случай, который мы считаем слишком сложным/странным для поддержки. Это похоже на (3), но здесь мы не утверждаем, что новый преобразователь дает «правильный» результат. Пользователи по-прежнему могут изменять ограничения, чтобы избежать странного случая, или закреплять и использовать --no-deps . Но в конечном итоге мы говорим «не делайте этого», и если пользователи проигнорируют это сообщение, то снова в какой-то момент мы удалим старый преобразователь со словами «мы вас предупреждали».

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

Кстати, где лучше всего размещать сценарии "вот крайний случай, о котором я подумал", чтобы они не потерялись? Я думаю, было бы полезно собрать как можно больше странных ситуаций заранее, хотя бы для того, чтобы мы могли пораньше начать писать тестовые случаи :-)

PS Вероятно, в рамках подготовки к новому распознавателю нам также следует выяснить, каковы «типичные» проблемы с ограничениями (на основе того, что есть в PyPI). Что касается меня, то довольно редко у меня есть что-то более сложное, чем «pip install". Было бы обидно настолько увязнуть в сложных случаях, что мы упустим из виду подавляющее большинство более простых.

  1. преобразователь слишком медленный (см. Conda). Если мне приходится выбирать между распознавателем более чем на 20 минут или текущим поведением, часто я хочу использовать текущее поведение (или, по крайней мере, попробовать; во многих случаях это даст удовлетворительный результат).

  2. метаданные неверны. не такая большая проблема сегодня, но легко представить себе случаи, которые должны быть разрешимы, но не являются. Метаданные PyPI находятся в худшем состоянии, чем метаданные conda/conda-forge, и это уже проблема для conda. если это неправильно, и как пользователь я не могу найти решение, я хочу получить отказ.

@rgommers Для версии 6 может работать параметр стиля «игнорировать конфликты версий в этом пакете», верно?

Спасибо, @rgommers - это хорошие моменты.

Резолвер слишком медленный, я бы посчитал его ошибкой. Если он не может дать достаточно эффективных результатов в простых случаях, на мой взгляд, он не подходит для этой цели. С другой стороны, если у вас есть очень сложная сеть ограничений, которая занимает больше времени с полным распознавателем (надеюсь, 20 минут — это преувеличение, я не считаю это приемлемым ни при каких обстоятельствах!), то мы входим в «вещи, которые мы считают слишком сложной для поддержки" территории. Иными словами, кто-нибудь пытался попросить conda предоставить «быстрый и грязный» неточный, но быстрый преобразователь? Если они этого не сделают (а я почти уверен, что они этого не сделают), то почему разумно ожидать, что это сделает pip?

Плохие метаданные — это определенно то, что я бы назвал «мы бы не поддерживали это» (помните, я говорю здесь о «после периода устаревания»!). Предоставление пользователям времени на исправление метаданных и предоставление опции escape-оговорки «игнорировать конфликты версий в пакете X» является достаточным ИМО, мы не должны ожидать, что мы сохраним весь старый механизм только потому, что некоторые люди не будут исправлять свои метаданные.

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

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

@jriddy Для этого подойдет стратегия разрешения «использовать существующую установку, если она совместима».

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

https://github.com/pradiunsg/zazo/

Для 6 вариант стиля «игнорировать конфликты версий в этом пакете» может работать, верно?

да вроде правильный вариант

(Надеюсь, 20 минут — это преувеличение, я не считаю это приемлемым ни при каких обстоятельствах!), то мы попадаем на территорию «вещей, которые мы считаем слишком сложными для поддержки». Иными словами, кто-нибудь пытался попросить conda предоставить «быстрый и грязный» неточный, но быстрый преобразователь? Если они этого не сделают (а я почти уверен, что они этого не сделают), то почему разумно ожидать, что это сделает pip?

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

Однако имейте в виду, что это _определенно_ понадобится, если только вы:

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

Плохие метаданные — это определенно то, что я считаю «мы бы не поддерживали это».

Справедливо. Однако вся позиция «мы не применяем правильные метаданные» здесь не помогает. Разве что недавно изменилось? (и я знаю, что это PyPI, а не пункт, но это связано).

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

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

Когда люди недовольны медленной работой Conda, это, по сути, всегда происходит из-за плохих метаданных. Имейте в виду, что вас будут обвинять в любой кажущейся медлительности, независимо от основной причины. Плохие метаданные иногда являются неправильным ограничением, но чаще отсутствие ограничения позволяет рассмотреть гораздо более старый, нежелательный вариант. В последнее время Conda значительно улучшилась, сделав одну маленькую вещь: удалив нашу старую коллекцию программного обеспечения, которая имела неадекватные (в основном слишком открытые) ограничения. Эти открытые ограничения заставили Conda исследовать действительно плохие решения, требующие большого количества понижений. Вот тут на решение ушло буквально несколько часов. Понижение — очень и очень дорогостоящие операции из-за того, что они могут каскадироваться, и каждый шаг становится менее ограниченным и более дорогим.

Проблема с менталитетом «мусор на входе, мусор на выходе» заключается в том, что как сопровождающие решателя вы держите сумку в руках. Если у вас нет очень хорошей эвристики для того, что является мусором, вы бессильны. В конечном итоге вы будете тем, кто должен выяснить, почему решатель работает медленно, изолировать проблемный пакет, а затем попросить источник проблемы исправить ситуацию. Поверь мне, это не лучшая позиция. Мы тратим массу времени, пытаясь объяснить людям, почему conda работает вечно или не будет работать с какой-то смесью conda-forge, bioconda или других сторонних каналов. В конечном итоге нам приходится выполнять детективную работу и сообщать этим сторонним каналам, что им нужно исправить. Это отстой.

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

@wolfv недавно исследовал использование libsolv для conda. В конечном итоге он был разочарован тем, что не мог заставить его давать те же ответы, что и conda. Это сводилось к этой разнице между подходами. Libsolv — это решатель с возвратом. Он может служить дополнительным скомпилированным дополнением к pip для ускорения работы, хотя я знаю, что вы чувствительны к тому, чтобы не включать скомпилированный код непосредственно в pip.

( @pradyunsg только что опубликовал августовское обновление в своем блоге .)

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

Но также: какие сроки мы считаем реалистичными для этого развертывания? Это во многом зависит от здоровья и свободного времени Прадюна, а также от возможности проверки кода другими сопровождающими пипсов, а также от того, получим ли мы какие-то гранты, на которые подаем заявку, но я думаю, что последовательность примерно такая:

  • построить логический рефакторинг: в процессе, где-то декабрь-февраль
  • UX-исследования и проектирование, построение тестовой инфраструктуры, обсуждение с нижестоящими пользователями и пользователями флагов конфигурации и графиков перехода: для этого нам нужно финансирование; самое раннее начало, вероятно, декабрь, займет 2-3 месяца
  • ввести абстракции, определенные в resolvelib/zazo , при проведении альфа-тестирования: это займет несколько месяцев, так что, по консервативным оценкам, май 2020 года?
  • принять лучшее разрешение зависимостей и провести бета-тестирование:

Это правильно? Что мне не хватает?

Я спрашиваю, потому что часть работы по сбору информации, по моему мнению, должен делать менеджер проекта и/или исследователь UX, а также потому, что некоторый прогресс на https://github.com/pypa/packaging-problems/issues/264 и другие вопросы могут помочь с проблемами, которые люди подняли здесь.

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

Поскольку использование неограниченных зависимостей или >= some_old_version является правилом, а не исключением для setup.py / pyproject.toml , это будет проблемой. Мне все равно, является ли это «неправильным ограничением» или решателю нужно сделать другой выбор — это состояние метаданных в PyPI.

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

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

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

Пример понижения версии, с которым должен бороться conda, а pip — нет: пользователи anaconda или miniconda с python 3 начинают с python 3.7. Пользователям иногда нужно установить что-то, что доступно только для python 3.6. Решатель должен понизить версию python и всех других пакетов, отличных от noarch. Это особый случай, который, возможно, можно было бы оптимизировать за счет особого поведения при изменении версии Python, но он иллюстрирует, как изменения в одном пакете могут потребовать понижения версии до другого. «До сих пор это работало» — глупая удача, а не то, что на самом деле работает все время.

Что касается ограничения версий, вы не можете применить это в самом решении. У вас есть свои ограничения, и любое «открытие по одной версии» не может быть достаточно общим, потому что оно отличается для каждого пакета. Однако вы можете вырезать метаданные по версии до решателя. Вот что такое «current_repodata.json» conda. Только последняя версия. Это заставляет вещи работать очень быстро, когда работает, но люди бы очень разозлились, если бы это были единственные реподаты. Вещи не будут воспроизводимы, и они будут разочарованы тем, что спецификации, которые работают сегодня, могут не работать завтра. Мы предоставляем запасной вариант к полному реподату, а также планируем ввести временные подмножества, при этом в определенные моменты времени будут доступны только самые новые версии. Постепенное открытие доступных данных индекса может быть более полезной концепцией с решателем поиска с возвратом.

pip _может_ даже понизить версию.

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

Следующее делает понижение setuptools - до тех пор, пока это первое, что видит pip:

pip install "setuptools < 20.0"

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

https://github.com/pradiunsg/zazo/

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

Пример понижения версии, с которым должен бороться conda, а pip — нет: пользователи anaconda или miniconda с python 3 начинают с python 3.7. Пользователям иногда нужно установить что-то, что доступно только для python 3.6. Решатель должен понизить версию python и всех других пакетов, отличных от noarch. Это особый случай, который, возможно, можно было бы оптимизировать за счет особого поведения при изменении версии Python, но он иллюстрирует, как изменения в одном пакете могут потребовать понижения версии до другого. «До сих пор это работало» — глупая удача, а не то, что на самом деле работает все время.

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

Другим примером является несогласованность между каналами. Недавний пример: мы были на Python 3.7.3, затем base получили 3.7.4 . Меня не волнуют эти различия версий, и большинству пользователей они не нужны. По умолчанию «ничего не делать» было бы намного лучше, чем «эй, .4 > .3 , давайте обновим это, а затем изменим каналы других пакетов на base , если нам нужно (даже если это понизит их)».

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

Звучит как очень полезное улучшение.

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

Да, это правда. Я думаю, что у каждой IDE, дистрибутива или «общего интерфейса для множества вещей» есть эта проблема.

Следующее делает понижение setuptools

Это запрошенное пользователем понижение. Я имел в виду косвенный (например, setuptools<20.0 в pyproject.toml`). Я думаю, это тоже сработает, но на практике это редкость.

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

100% согласен. Это то, с чем нужно обращаться очень осторожно. Но, наоборот, пытаться выработать разумное поведение для любого старого барахла нецелесообразно — мы должны где- то подвести черту.

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

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

«Правильно» не имеет значения для пользователей, когда они сломлены вашими изменениями. Любое изменение в поведении приведет в бешенство некоторое количество пользователей. Сказать им, что их рабочий процесс неправильный и что им нужно измениться, было не очень эффективной стратегией для меня. Я думаю, вам нужно играть на слух. Я, конечно, не хотел бы поддерживать старый преобразователь навсегда, но вам, вероятно, нужно дать людям возможность сохранить его — например, сделать его плагином, который кто-то другой принимает и поддерживает, и люди могут установить его отдельно от pip.

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

Да, но что такое "старый хлам"? Что его отличает? Как насчет плохого хлама по сравнению с хорошим хламом (учитывая, что новое не всегда лучше)? Мой совет — потратить много времени на то, чтобы решатель был легко отлаживаемым. Сделайте так, чтобы пользователям (а не только вам как эксперту) было легко отслеживать, где что-то идет не так, чтобы было легко определить, когда возникают проблемы с неверными метаданными, и что это за неверные метаданные. Это навык, которого в настоящее время нет у большинства пользователей, и, честно говоря, большинство пользователей, которых я видел, не хотят иметь этот навык. Я не думаю, что вы (или conda в этом отношении) когда-либо сможете иметь полностью точную автоматическую эвристику для плохого и хорошего.

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

@rgommers , conda 4.7 перешел к этому - требуется явная спецификация python для изменения младших версий. Люди ненавидели это. Я понятия не имею, какую часть населения составляют вокалисты, но многим людям очень, очень не нравится, что раньше они могли что-то conda install , а теперь не могут. Их не очень волнует причина, и они в основном успокаиваются ответом, но тем временем мы все еще сталкиваемся с враждебностью, с которой приходится иметь дело. Просто еще один пример

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

Другим примером является несогласованность между каналами. Недавний пример: мы были на Python 3.7.3, потом в базу попал 3.7.4. Меня не волнуют эти различия версий, и большинству пользователей они не нужны. По умолчанию «ничего не делать» было бы намного лучше, чем «Эй, .4 > .3, давайте обновим это, а затем изменим каналы других пакетов на базовые, если нам нужно (даже если это понизит их)».

Это гораздо более сложный момент. Вы в основном предлагаете разные критерии оптимизации. Возможно, вы видели текущие 11 шагов в нашем блоге по адресу https://www.anaconda.com/understanding-and-improving-condas-performance/ .

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

Привет, спасибо @msarahan за упоминание меня в этом выпуске. Хотел зайти раньше, но не нашел времени.

Действительно, я довольно много экспериментировал с использованием libsolv в качестве решателя для спецификаций conda. И это действительно работает — оставшаяся разница в том, что conda не очень заботится о номере сборки, а libsolv в том, как он закодирован (и с решателем с возвратом). Даже при использовании полного реподата libsolv работает очень быстро — я бы даже сказал, что скорость libsolv достаточно высока, чтобы не раздражать :)

Мой большой вклад в libsolv заключался в том, чтобы сделать его кроссплатформенным, чтобы теперь он компилировался в Windows, OS X и Linux.

Я бы полностью рекомендовал использовать libsolv для нового распознавателя, даже несмотря на то, что это кусок скомпилированного кода (по крайней мере, он быстрый), и @mlschroe может помочь — он очень помог с поддержкой libsolv для conda matchspec.

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

Возможно, вы видели текущие 11 шагов в нашем блоге по адресу https://www.anaconda.com/understanding-and-improving-condas-performance/ .

Действительно я сделал. Это был хороший пост в блоге.

Вы в основном предлагаете разные критерии оптимизации.

не совсем. Я думаю, что ваше _"ограничение двоичной совместимости по сравнению с простым и простым ограничением версии"_ просто указывает на то, что я, вероятно, упускаю. Я ожидаю, что ни один пакет не должен иметь python >= 3.7.4 или == 3.7.4 в своих метаданных, это всегда == 3.7 (только что проверил на scipy, meta.yaml говорит python и conda_forge.yml говорит max_py_ver: '37' - имеет смысл). Таким образом, введение 3.7.4 ничего не должно делать - резольвер, выбирающий 3.7.3 и ничего не меняющий, намного дешевле (и действителен в соответствии с вашими 11 шагами), чем форсировать 3.7.4 и запускать цепочка повышения/понижения.

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

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

+1

Также: сделайте (сохраните) его как можно более ремонтопригодным. Это хорошая вещь с pip теперь, если это испортит, обычно можно сделать cd site-packages && rm -rf troublesome_package (возможно, с последующей переустановкой с --no-deps ), и все снова заработает. Таких, как conda , apt и друзей, восстановить таким образом гораздо сложнее.

Вы в основном предлагаете разные критерии оптимизации.

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

В пакетах нет python >= 3.7.4 и == 3.7.4. Стандарт упаковки conda должен иметь верхнюю и нижнюю границы. Как правило, они автоматически определяются conda-build с использованием информации, предоставленной автором рецепта, относительно того, сколько мест в версии следует рассматривать как совместимый диапазон. Пакеты имеют такие ограничения, как >=3.7.2,<3.8.0a0, с неловкостью 0a0, объясняющей тот факт, что предварительные версии ниже выпусков .0 и, таким образом, будут соответствовать спецификации <3.8.0, где люди не действительно ожидайте этого.

Пакеты также имеют связанный с ними канал. Этот канал фактически является частью оптимизации версии: https://github.com/conda/conda/blob/4.6.7/conda/resolve.py#L1074 — канал похож на суперверсию, на одно место впереди основная версия пакета. Если решение не должно изменять python, то спецификация python не может быть python == 3.7 - это диапазон, и канал будет влиять на этот диапазон. В частности, имея спецификацию python == 3.7 и начиная с установки из канала defaults , добавление канала conda-forge приведет к большому оттоку, потому что вы ввели новые пакеты python, которые выше в «версии» (включая канал), и ваша спецификация python допускает это изменение.

В Conda 4.7 введено гораздо более агрессивное «замораживание» спецификаций, и я почти уверен, что именно такое поведение вам и нужно. Хотя это довольно сложно. Это сводится к замораживанию только тех вещей, которые не противоречат вашим явным спецификациям. Как вы определяете «конфликт» — сложная часть. Мы считаем, что лучше не замораживать то, что мешает решателю предоставить пользователю новейшие пакеты, которые являются частью графа зависимостей для этого пакета. Это замораживание стоит упомянуть, потому что оно может быть выполнено для каждой спецификации для pip так, как это не может сделать conda. Я думаю, что это может быть отличной оптимизацией для решателя с возвратом.

Также: сделайте (сохраните) его как можно более ремонтопригодным. Это хорошая вещь с pip сейчас, если он испортится, обычно можно сделать cd site-packages && rm -rf Trouble_package (возможно, с последующей переустановкой с --no-deps), и все снова заработает. Подобные conda, apt и друзьям гораздо сложнее восстановить таким образом.

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

(Касательная libsolv: когда я работал в RH, я схватил https://pypi.org/project/solv/, чтобы закрыть лазейку безопасности «pip install solv» в Fedora, поскольку процесс сборки libsolv не генерирует sdist или колесный архив на данный момент, не говоря уже о публикации его в PyPI. Рад поболтать со всеми, кто может быть заинтересован в создании этих реальных привязок библиотек с пакетной копией libsolv, а не с безобидным заполнителем, как сейчас)

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

Yum/DNF предлагает это через свою опцию --skip-broken (в DNF этот флаг является псевдонимом для --setopt=strict=0 ), и я думаю, что преобразователь pip должен предлагать аналогичную опцию.

@ncoghlan Ах да. В этом есть смысл.

Параметр стиля «игнорировать конфликты версий в этом пакете»

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

Тогда мы на одной волне. :)

@ncoghlan ответил на мой предложенный график на distutils-sig и сказал, что это звучит разумно.

@pradyunsg - с нетерпением жду вашего следующего ежемесячного обновления!

Я потратил некоторое время на то, чтобы еще раз взглянуть на это и зарегистрировал # 7317.

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

Я только что закрыл #7317. Насколько я могу судить, разрешение зависимостей теперь отделено (достаточно) от логики построения метаданных. Рефакторинг логики сборки продвинулся хорошо, и теперь он больше не блокирует дальнейший прогресс.

Теперь мы можем начать работать над реализацией абстракций [resolvelib] в pip, используя ссылки из [passa] и распознавателя поэзии, где это уместно. :)

@pradyunsg Я планирую извлечь базовый преобразователь (на основе PubGrub) из кодовой базы Poetry (см. https://github.com/sdispater/poetry/tree/master/poetry/mixology). Он в основном отделен от остального кода, но все еще есть ссылки на внутренние части, которые мне нужно абстрагировать.

Если вы заинтересованы в том, чтобы помочь с этим, пожалуйста, дайте мне знать. Идея состоит в том, чтобы иметь автономную реализацию алгоритма PubGrub, которую могут использовать третьи стороны, и которая будет размещена на https://pypi.org/project/mixology/ , где в настоящее время хранится код старого преобразователя.

@sdispater Определенно! Я не знаю, смогу ли я помочь напрямую (временные ограничения), но было бы здорово, если бы вы могли отделить порт PubGrub от остальной поэзии!

Одна из вещей, которая была бы действительно хороша, заключалась бы в том, чтобы иметь согласованный уровень абстракции, чтобы pip, поэзия и pipenv использовали одни и те же абстракции. Прямо сейчас у нас есть zazo (мой), mixology (поэзия) и resolvelib (pipenv) — все они определяют своего рода уровень абстракции, и они немного отличаются, но (смехотворно!) похожи. Если вы открыты для этого, дайте нам знать!

К вашему сведению, мы ( @wolfv и команда @QuantStack в целом) ответили на запрос предложений для преобразователя зависимостей pip.

Предлагаемый подход состоит в том, чтобы принять библиотеку C libsolv и внести поддержку формата ограничений версии pip в libsolv. Мы бы предоставили библиотеку C через новые привязки Python.

Libsolv — это закаленная в боях библиотека, лежащая в основе экосистемы RPM, и поэтому уже используемая в промышленных масштабах.

  • Libsolv's распространяется под лицензией BSD-3-Clause.
  • Libsolv поддерживает несколько пакетов и форматов репозиториев, таких как rpm , deb ,
    haiku , conda , arch . Важно отметить разнообразие форматов и способов выражения
    ограничения зависимостей показывают, что это подключаемая система, которая должна быть в состоянии
    чтобы приспособить синтаксис pip для ограничений версий зависимостей.
  • Используя libsolv вместо решателя conda в тонкой обертке mamba, мы
    может значительно улучшить производительность conda. (медленность conda в разрешении пакетов с большими каналами была нашей основной мотивацией для работы над мамбой).
  • Он работает кроссплатформенно на Windows, OS X и Linux. ( @wolfv сделал порт libsolv для Windows)
  • Он выполняет полное SAT-решение, чтобы найти оптимальные комбинации зависимостей, и, если это не удается, он возвращает действенные подсказки для разрешения конфликта.

Предлагаемый подход заключается в использовании библиотеки libsolv C.

Потребуется запасной вариант для платформ, которые libsolv не поддерживает (например, активно ведется работа над поддержкой AIX в pip, а вы не упомянули BSD). Таким образом, libsolv как доступный вариант производительности кажется мне правдоподобным, но мы не в состоянии использовать только его. (Есть ли версия libsolve на чистом Python, то есть что-то, что дает те же результаты, только медленнее?)

Кроме того, как будет работать get-pip.py? Должны ли мы включать бинарники для libsolv для всех возможных платформ? Опять же, я бы предположил, что нет, мы бы использовали запасной вариант на чистом питоне.

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

Привет @pfmoore

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

Я думаю, что для начальной загрузки можно было бы иметь чистый Python pip, который использует текущий механизм для разрешения, который затем устанавливает необходимую библиотеку распознавателя на основе libsolv. Например, можно закрепить точный пакет привязок Python, специфичных для libsolv + pip, и установить их из boostrap-pip, как вы описываете. Для меня это звучит вполне выполнимо, но вы, возможно, лучше знаете, что для этого нужно...

Я думаю, что дополнительная поддержка платформы не должна быть такой сложной.

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

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

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

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

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

Насколько я понимаю, libsolv использует полностью SAT-решатель для разрешения зависимостей и требует загрузки информации о зависимостях, прежде чем он начнет решать. Но PyPI на данный момент хранит метаданные зависимостей для каждого пакета. Даже если вы проигнорируете природу setup.py , зависящую от времени выполнения, будет сложно эффективно получить информацию, необходимую для SAT-решателя.

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

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

Эти файлы .solv предназначены только для кэширования, libsolv они не нужны для решения. Но я согласен с тем, что динамическая природа зависимостей PyPI затрудняет использование решателя SAT.

(Подробнее см. https://docs.google.com/document/d/1x_VrNtXCup75qA3glDd2fQOB2TakldwjKZ6pXaAjAfg/edit.)

(Обратите внимание, что решатель SAT — это просто решатель с возвратом, который также выполняет изучение предложений, если он сталкивается с конфликтом, поэтому я думаю, что можно использовать решатель SAT для PyPI. Но это должен быть решатель, который позволяет динамически добавлять предложения. при решении.)

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

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

Я подал заявку №7406 для дальнейшего обсуждения технических компромиссов — @sdispater , @techalchemy , @uranusjr , @wolfv. Я был бы признателен, если бы мы могли продолжить обсуждение различных вариантов конструкции резольвера.

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

Обновление статуса: PSF удалось получить некоторое финансирование от службы поддержки открытого исходного кода Mozilla и Инициативы Чана Цукерберга, чтобы нанять подрядчиков для работы над распознавателем точек и связанными с ним проблемами взаимодействия с пользователем . Вы можете ознакомиться с нашей дорожной картой (которую мне нужно отполировать), а также сообщениями в блогах, форумах и списках рассылки, а также заметками с недавних встреч , чтобы быть в курсе. Я скоро опубликую что-нибудь об этом на distutils-sig и на форуме по упаковке экземпляра Python Discourse .

Мы стремимся подготовить функцию распознавателя пипсов к выпуску в пипсе 20.2 в июле. (Согласно ежеквартальному графику выпуска пипсов, непредвиденные трудности могут задержаться до 20,3 в следующем квартале.)

@uranusjr :

Насколько я понимаю, libsolv использует полностью SAT-решатель для разрешения зависимостей и требует загрузки информации о зависимостях, прежде чем он начнет решать. Но PyPI на данный момент хранит метаданные зависимостей для каждого пакета. Даже если вы проигнорируете природу setup.py, зависящую от времени выполнения, будет сложно эффективно получить информацию, необходимую для решателя SAT.

Прототип команды pip resolve в #7819 использует два метода для эффективного получения этой информации (подробности см. в этом выпуске):

  1. > Извлечение содержимого файла METADATA из URL-адреса колеса без фактической загрузки колеса.
  2. > Кэширование результата каждого вызова self._resolve_one() в постоянном файле json.

Техника, используемая для (1), позволяет очень быстро преобразовать URL-адрес колеса в список строк требований, от которых он зависит, при этом загружая только несколько КБ содержимого самого колеса. Затем прототип в # 7819 гарантирует, что req.populate_link() вызывается для каждого из зависимых требований, возвращаемых self._resolve_one() , и сохраняет сопоставление (==Requirement, url) -> [list of (==Requirement, url) non-transitive dependencies] в постоянном файле кеша json. (1) быстро получает новую информацию, (2) позволяет быстро запрашивать старую информацию.

Хотя я еще не знаком с libsolv, я считаю, что записи этого сопоставления URL-адреса требования с зависимостями и их URL-адресами могут быть в точности атомарными входными данными, требуемыми решателем SAT. Как показано в #7189, постоянный файл кеша зависимостей json приводил к тому, что вызовы pip resolve становились полными без операций после первого запуска, с тех пор занимая 800-900 мс в командной строке. Если используются методы из (1) и (2), я полагаю, что можно позволить решателю SAT работать до завершения каждый раз, когда вызывается pip, без ожидания невероятно долгого времени. Вероятно, было бы несложно попробовать взломать libsolv поверх прототипа в #7189, чтобы сделать это число более конкретным.

@techalchemy :

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

Штаны имели некоторый код, который упрощал предоставление компилятору и компоновщику проекта на основе setup.py (#6273), но позже мы удалили его (см. #7016) в пользу возможности сборки C/C++ в штанах без использования setup.py , что подходило для нашего варианта использования внутри Twitter, которому нужно было только создать общую библиотеку для пользовательских операторов TensorFlow . Мы размещаем готовые двоичные файлы для статически связанных архивов GCC и binutils на нашем s3 для OSX и Linux (см. https://github.com/pantsbuild/binaries/), поэтому пользователям брюк не нужно устанавливать ничего, кроме python и JDK. использовать штаны вообще.

Я был бы заинтересован в том, чтобы помочь провести мозговой штурм и/или разработать какой-либо инструментарий для переносимой сборки C и C++, который может позволить pip надежно зависеть от libsolv на всех поддерживаемых платформах.

@cosmicexplorer

Штаны имели некоторый код, который упрощал предоставление компилятору и компоновщику проекта на основе setup.py (#6273), но позже мы удалили его (см. #7016) в пользу возможности сборки C/C++ в штанах без использования setup.py, что подходило для нашего варианта использования в Twitter, которому нужно было только создать общую библиотеку для пользовательских операторов TensorFlow. Мы размещаем готовые бинарные файлы для статически связанных архивов GCC и binutils на нашем s3 для OSX и Linux (см. сборка штанов/бинарные файлы), так что пользователям штанов не нужно устанавливать ничего, кроме Python и JDK, для использования штанов вообще.

Работа компилятора/линкера очень интересна! Также обсуждается отделение компилятора от setup.py (или бэкэнд сборки PEP 517 в целом). На самом деле это не связано с распознавателем (по крайней мере, напрямую), но вам может быть интересно: https://discuss.python.org/t/how-do-we-get-out-of-the-business-of- вождение-c-компиляторы/2591

@cosmicexplorer

Я был бы заинтересован в том, чтобы помочь провести мозговой штурм и/или разработать какой-либо инструментарий для переносимой сборки C и C++, который может позволить pip надежно зависеть от libsolv на всех поддерживаемых платформах.

Я и @wolfv смотрели на это для создания частей стека менеджера пакетов DNF на всех основных поддерживаемых платформах для мамбы и моей личной работы с DNF. На данный момент libsolv теперь можно собирать для Windows, Linux, macOS, BSD, Haiku OS, и я смутно знаю, что его помещают в различные системы UNIX как часть использования DNF в UNIX. Я знаю, что @dralley также сделал бинарные колеса solv доступными для ~основных платформ, поддерживаемых PyPI~ Linux, используя manylinux2014 на PyPI .

Теперь у нас есть pip 20.1b1, бета-версия, которая включает в себя очень раннюю (альфа) версию нового преобразователя (см. # 8099 для получения информации об этом и опроса, в котором люди могут оставить отзыв). Вот объявление . И https://github.com/pypa/pip/issues/7951#issuecomment -617851381 перечисляет некоторые места, где мы публиковали бета-версию.

Вышел pip 20.1, включающий альфа-версию преобразователя.

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

Мы столкнулись с задержками, когда выясняли #8371, как лучше отображать определенные сообщения об ошибках и обрабатывали кучу других неприятных вещей; см. https://github.com/pypa/pip/projects/6 и https://github.com/pypa/pip/projects/5 , чтобы узнать больше о нашем прогрессе. #8206 — это обсуждение предстоящей бета-версии, pip 20.2b2, которую, я надеюсь, мы сможем опубликовать к концу июня.

Я разместил наш полугодовой отчет в блоге PSF . Одна ключевая вещь, которую нужно знать: позже в этом месяце мы выпустим pip 20.2 , в котором будет бета-версия нового преобразователя зависимостей (у pip 20.1 была альфа-версия), доступная через необязательный флаг « --use-feature=2020-resolver ». Мы будем много публиковать pip 20.2 и просить многих пользователей протестировать новый преобразователь.

В соответствии с #8511 мы выпустили пункт 20.2 . Этот выпуск включает бета-версию преобразователя зависимостей следующего поколения . Он значительно более строгий и последовательный, когда получает несовместимые инструкции, и уменьшает поддержку определенных типов файлов ограничений, поэтому некоторые обходные пути и рабочие процессы могут нарушаться. Пожалуйста, протестируйте его с флагом --use-feature=2020-resolver . Ознакомьтесь с нашим руководством по тестированию и миграции, а также по сообщениям о проблемах . Новый сопоставитель зависимостей отключен по умолчанию, поскольку он еще не готов к повседневному использованию .

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

Пожалуйста, расскажите об этом, указав на это сообщение в блоге — расскажите об этом в Hacker News, Reddit, Twitter, Facebook, Dev.to , Telegram, в соответствующих ответах на Stack Overflow и в ваших любимых Slacks и Discords. Большинство людей, на которых это повлияет, не следят за новостями разработчиков Python. Помогите им получить информацию до октября и помогите нам получить их отчеты об ошибках.

(Копирую мою заметку из #988.)

@zooba спросил :

Как вы думаете, стоит ли нам обновлять версию pip в комплекте с Python 3.9 на данном этапе (для первого RC)?

Точно так же нужно ли обновлять Python 3.8 для следующего выпуска?

Я предполагаю, что да, после выпуска исправления в начале следующей недели, да, но @pfmoore @xavfernandez @cjerdonek @uranusjr @pradyunsg @dstufft что вы думаете?

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

То же самое здесь, было бы неплохо включить 20.2.x в 3.9 для более легкого доступа к новому преобразователю.

Как вы думаете?

Вы правы, это план. :)

Хорошо, ответил на python-dev - да, версия pip, входящая в состав Python 3.8 и 3.9, должна быть обновлена ​​до 20.2.x.

Отдельно на паблике отмечу вот некоторые незавершенные работы:

В течение следующих ~6-8 недель я буду добиваться широкой огласки, чтобы пользователи попробовали использовать новый пункт. Я подозреваю, что проблема будет не столько в том, что "этот отдельный пакет не будет установлен"; это будут неожиданные конфликты между конкретными пакетами, возможно, зависящие от среды и конкретных файлов ограничений. Мы пытаемся получить ранние отзывы с помощью опроса , чтобы затем исправить ошибки, настроить больше автоматизированного тестирования и т. д., а также чтобы эти исходные пакеты могли получить предупреждение и выпустить исправленные пакеты до пункта 20.3 (пример : проблема TensorFlow/numpy/scipy в https://github.com/pypa/pip/issues/8076#issuecomment-666493069).

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

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

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

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

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

Мы получили небольшое внимание в Twitter ( 1 , 2 ) и Reddit (кто-нибудь хочет ответить на этот вопрос о финансировании PyPA ?).

@zooba написал (относительно комплектации):

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

Я считаю, что --use-feature=2020-resolver для меня обычно решает больше проблем, чем вызывает.

не слишком ли поздно предлагать начальное развертывание через:

предложенный псевдокод 20.3

try:
    _2020_resolver()
except:
    legacy_resolver()

что означало бы, по крайней мере, для моих проектов, все они прошли бы без изменений

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

предложенный псевдокод 20.4

try:
    _2020_resolver()
except:
    if not use_legacy_resolver:
        raise
    legacy_resolver()

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

@di вызвался помочь собрать несколько добровольцев, чтобы помочь с первым ответом. Эти добровольцы ответят на вопросы и помогут с нагрузкой пользователей после выхода нового пункта — в Twitter, StackOverflow и GitHub — и сообщат о реальных ошибках команде сопровождающих/участников.

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

Вот мой примерный план:

  • Начать обсуждение на обсуждении.python.org с просьбой о поддержке
  • Направляйте людей на канал Slack, который может служить каналом связи между всеми.
  • Начните документ с изложением некоторых часто задаваемых вопросов и наших ответов
  • Включить дерево решений для новой проблемы -> проблема с сортировкой
  • Поделитесь этим с каналом, как только станет известна дата выхода.
  • Попробуйте и примерно запланируйте, чтобы волонтеры были онлайн и сортировали в течение нескольких дней после релиза.

Спасибо, @ди. Мы ждем до завтра, чтобы получить одобрение от других сопровождающих. И мы планируем выпустить 20,3 пункта в среду или четверг, 28 или 29 октября.

@di Я вижу, что твой план одобрен. Пожалуйста продолжай!

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

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

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


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

В течение последних нескольких месяцев мы получаем постоянный поток новых проблем от людей, тестирующих новый преобразователь в 20.2 и бета-версии 20.3, pip 20.3b1 . Эти отчеты помогли нам улучшить преобразователь, исправив ошибки и улучшив UX его результатов. Мы также существенно улучшили руководство пользователя «что изменилось» частично в ответ на отзывы о бета-версии.

Вот мой примерный план:

* Start a discussion on discuss.python.org asking for support

* Direct folks to a Slack channel that could serve as a communication channel between everyone

* Start a document outlining some FAQ and our responses

* Include a decision tree for new issue -> triaged issue

* Share this with the channel once we have a known release date

* Try and roughly schedule volunteers to be online & triaging in the days following the release

@di Я понимаю, что постоянная неопределенность и задержки, вероятно, помешали вам составить расписание. Новая дата релиза — завтра, понедельник, 30 ноября. Если теперь у вас есть тема для обсуждения и дерево решений, которыми вы можете поделиться, поделитесь ими!

Был выпущен pip 20.3, и по умолчанию он имеет новый преобразователь! Вот объявление о выпуске в блоге PSF: https://blog.python.org/2020/11/pip-20-3-release-new-resolver.html .

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