Руководство для разработчиков ядра SciPy#

Процесс принятия решений#

SciPy имеет формальную модель управления, задокументированную в Управление проектом SciPy. Следующий раздел неформально документирует, что происходит на практике при принятии решений о коде и правах на коммиты. Формальная модель управления является руководящей, нижеприведенное предоставлено только для контекста.

Код#

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

Любое нетривиальное изменение (где тривиальное означает опечатку или однострочный коммит обслуживания) должно проходить через pull request (PR). Оно должно быть проверено другим разработчиком. В случае, если проверка не происходит достаточно быстро и важно, чтобы PR был слит быстро, автор PR должен отправить сообщение на форум, указав, что намерен слить этот PR без проверки в время X по причине Y, если никто не проверит его до этого.

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

Права на коммит#

Права на коммит определяются Советом по управлению SciPy; изменения в правах на коммит будут объявлены на форуме scipy-dev.

Принятие решений о новых функциях#

Общее правило принятия решения для предложенной новой функции до сих пор было условным:

  1. Метод применим во многих областях и «общепризнанно» полезен,

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

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

  4. Кто-то хочет внести свой вклад, и

  5. Кто-то хочет это проверить.

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

Хотя сложно дать строгие правила о том, что означает «общеполезно и общепризнанно работающим», может помочь взвесить следующее друг против друга:

  • Используется ли метод на практике в различных областях? Сколько предметных знаний требуется для его правильного использования?

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

  • Рассмотрим класс эквивалентности схожих методов/функций, которые обычно ожидаются. Среди них, какой в принципе был бы минимальный набор, чтобы не было явного упущения в предлагаемых функциях? Сколько всего это составит? Покрывает ли включение одного представительного метода большинство случаев использования? Было бы в принципе разумно включить всё из минимального набора в модуль?

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

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

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

Разработка на GitHub#

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

Метки и вехи#

Каждый issue и pull request обычно получает как минимум две метки: одну для темы или компонента (scipy.stats, Documentation, и т.д.), и один для характера проблемы или запроса на включение (enhancement, maintenance, defect, и т.д.). Другие метки, которые могут быть добавлены в зависимости от ситуации:

  • good-first-issue: для проблем, подходящих для решения новыми участниками.

  • needs-work: для pull requests, у которых есть комментарии рецензентов, которые не были обработаны.

  • needs-decision: для проблем или запросов на включение, требующих решения.

  • needs-champion: для pull request'ов, которые не были завершены оригинальным автором, но стоит возродить.

  • backport-candidate: исправления ошибок, которые следует рассмотреть для обратного портирования менеджером выпуска.

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

Рабочий процесс проверки pull request#

При проверке запросов на включение, пожалуйста, используйте функции рабочего процесса запросов на включение, см. Использование функций рабочего процесса.

Работа с pull request'ами#

  • При слиянии вкладов коммиттер отвечает за обеспечение соответствия требованиям, изложенным в Вклад в SciPy. Также проверьте, что новые возможности и нарушения обратной совместимости обсуждались на форуме scipy-dev.

  • Новый код добавляется через pull request (PR).

  • Объедините новый код с зелёной кнопкой. В случае конфликтов слияния попросите автора PR перебазировать (это может потребовать предоставления некоторых git инструкций).

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

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

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

  • Убедитесь, что метки и веха на объединённом PR установлены правильно.

  • Когда вы хотите отклонить PR: если это очевидно, вы можете просто закрыть его и объяснить почему. Если это не очевидно, то лучше сначала объяснить, почему вы считаете, что PR не подходит для включения в SciPy, затем дать второму коммиттеру прокомментировать или закрыть.

Обратный порт#

Все pull requests (содержат ли они улучшения, исправления ошибок или что-то ещё) должны быть направлены в main. Только исправления ошибок являются кандидатами для обратного переноса в ветку поддержки. Стратегия обратного переноса для SciPy заключается в том, чтобы (a) переносить обратно только важные исправления и (b) делать это только тогда, когда есть уверенность, что будет выпущен новый релиз с исправлениями ошибок в соответствующей ветке поддержки. Обычно разработчик, который объединяет важное исправление ошибки, добавляет backport-candidate метка и пингует менеджера выпуска, который решает, будет ли и когда выполнен бэкпорт. После завершения бэкпорта backport-candidate метку нужно снова удалить.

Хорошая стратегия для запроса на перенос изменений (backport pull request) — объединить несколько запросов из основной ветки, чтобы снизить нагрузку на тесты непрерывной интеграции и уменьшить загромождение истории ветки обслуживания коммитами слияния. Обычно лучше иметь один коммит для каждого запроса из основной ветки, представленного в запросе на перенос. Таким образом, история остаётся ясной и может быть легко отменена при необходимости.

Примечания к выпуску#

Когда PR объединяется, подумайте, нужно ли упоминать изменения в примечаниях к выпуску. Что нужно упомянуть: новые функции, обратно несовместимые изменения, устаревания и «другие изменения» (всё остальное, достаточно примечательное, см. старые примечания к выпуску для примеров того, что стоит упомянуть).

Записи примечаний к выпуску поддерживаются на вики. Менеджер выпуска соберет контент оттуда и интегрирует его в html документацию. Мы используем этот механизм, чтобы избежать конфликтов слияния, которые возникли бы, если каждый PR изменял бы один и тот же файл в doc/release/ напрямую.

Изменения можно отслеживать (Лента Atom) и извлечены (вики — это git-репозиторий: https://github.com/scipy/scipy.wiki.git).

Другие#

Перекрестные ссылки: Перекрестные ссылки на issues и pull requests на GitHub часто полезны. GitHub позволяет делать это с помощью gh-xxxx или #xxxx с xxxx номер issue/PR. gh-xxxx формат настоятельно рекомендуется, потому что ясно, что это ссылка на GitHub. Старые задачи содержат #xxxx которая касается тикетов Trac (который мы использовали до GitHub).

Соглашение об именовании PR: Pull requests, issues и commit messages обычно начинаются с трёхбуквенного сокращения, такого как ENH: или BUG:. Это полезно для быстрого понимания характера коммита/PR/проблемы. Полный список сокращений см. в написание сообщения коммита.

Лицензирование#

SciPy распространяется под модифицированная (3-пунктная) лицензия BSD. Весь код, документация и другие файлы, добавленные в SciPy участниками, лицензированы по этой лицензии, если в исходном коде не указана явно другая лицензия. Участники сохраняют авторские права на код, который они написали и представили для включения в SciPy.

Другие лицензии, совместимые с модифицированной лицензией BSD, которую использует SciPy, — это 2-пунктная BSD, MIT и PSF. Несовместимые лицензии — это GPL, Apache и пользовательские лицензии, требующие указания авторства/цитирования или запрещающие использование в коммерческих целях.

PR часто отправляются с содержимым, скопированным или полученным из нелицензированного кода или кода с лицензией по умолчанию, несовместимой с лицензией SciPy. Например, код, опубликованный на StackOverflow, покрывается лицензией CC-BY-SA, которая несовместима из-за условия share-alike. Эти вклады не могут быть приняты для включения в SciPy, если оригинальный автор кода не готов (пере)лицензировать свой код под модифицированной BSD (или совместимой) лицензией. Если оригинальный автор согласен, добавьте комментарий с указанием этого в исходные файлы и перешлите соответствующую переписку на форум scipy-dev.

Еще одним распространенным случаем является перевод или производный код из R, Octave (оба с лицензией GPL) или коммерческого приложения. Такой код также не может быть включен в SciPy. Простая реализация функциональности с тем же API, что и в R/Octave/…, допустима, если автор не смотрел на исходный код с несовместимой лицензией.

Нумерация версий#

Нумерация версий SciPy соответствует PEP 440. Выпущены финальные версии, которые являются единственными версиями, появляющимися на PyPI, пронумерованы MAJOR.MINOR.MICRO где:

  • MAJOR является целым числом, указывающим основную версию. Он меняется очень редко; изменение в MAJOR указывает на крупные (возможно, обратно несовместимые) изменения.

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

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

Выпущенные альфа-, бета- и rc (релиз-кандидат) версии нумеруются как финальные версии, но с постфиксами a#, b# и rc# соответственно, с # целое число. Версии для разработки имеют постфикс .dev0+.

Примеры допустимых строк версий SciPy:

0.16.0
0.15.1
0.14.0a1
0.14.0b2
0.14.0rc1
0.17.0.dev0+ac53f09

Установленная версия SciPy содержит следующие идентификаторы версий:

scipy.__version__            # complete version string, including git commit hash for dev versions
scipy.version.short_version  # string, only major.minor.micro
scipy.version.version        # string, same as scipy.__version__
scipy.version.full_version   # string, same as scipy.__version__
scipy.version.release        # bool, development or (alpha/beta/rc/final) released version
scipy.version.git_revision   # string, git commit hash from which scipy was built

Устаревшие функции#

Существуют различные причины для удаления существующей функциональности: она содержит ошибки, API непонятен, она заменена функциональностью с лучшей производительностью, её нужно переместить в другой подмодуль SciPy и т.д.

В целом, не рекомендуется удалять что-либо без предупреждения пользователей о предстоящем удалении. Поэтому перед удалением чего-либо из публичного API следует сделать следующее:

  1. Предложить устаревание функциональности на форуме scipy-dev и получить согласие, что это допустимо.

  2. Добавить DeprecationWarning для него, в котором указано, что функциональность была устаревшей, и в каком выпуске. Для Cython API см. Устаревание публичных Cython API для практических шагов.

  3. Упомяните об устаревании в примечаниях к выпуску для этого релиза.

  4. Подождите как минимум 6 месяцев после даты выпуска релиза, который ввел DeprecationWarning перед удалением функциональности.

  5. Упомянуть удаление функциональности в примечаниях к выпуску.

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

Возможно, есть причина игнорировать эту политику устаревания для конкретного устаревания; это всегда можно обсудить на форуме scipy-dev.

Вендорный код#

Многие части кодовой базы SciPy поддерживаются в других местах и включаются в SciPy. Некоторые из этих частей включаются как git подмодули, например, xsf, или размещены под subprojects каталог (или оба).

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

  1. подмножество исходного репозитория включено с помощью скрипта.

    (Возможно, эти части будут перемещены под subprojects в будущем.)

  2. Код был скопирован в SciPy и изменён с тех пор.

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

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

Части кодовой базы, которые включены с помощью скрипта:

  • PRIMA, в scipy/_lib/pyprima

Части кодовой базы, содержащие код, скопированный из вышестоящего источника, включают:

Пожалуйста, обратитесь к scipy/scipy#21232 для дополнительных сведений и отслеживания вендорированного кода в репозитории.

Распределение#

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

Зависимости#

Зависимости — это то, что пользователь должен установить для использования (или сборки/тестирования) пакета. Они часто вызывают проблемы, особенно если они не являются опциональными. SciPy старается минимизировать зависимости; текущие обязательные и опциональные зависимости времени сборки можно увидеть в Файл конфигурации SciPy, pyproject.toml. Единственная необязательная зависимость во время выполнения — NumPy.

Кроме того, конечно, необходимы компиляторы C, C++ и Fortran для сборки SciPy, но мы не считаем их зависимостями, и поэтому они не обсуждаются здесь. Подробности см. в Сборка из исходного кода.

Когда пакет предоставляет полезную функциональность и предлагается как новая зависимость, также стоит рассмотреть, имеет ли смысл вендорить (т.е. поставлять копию с SciPy) пакет вместо этого. Например, декоратор заимствован в scipy._lib.

Проблемы с обработкой зависимостей#

Существуют некоторые проблемы с тем, как инструменты упаковки Python обрабатывают зависимости, о которых сообщают проекты. Поскольку SciPy регулярно получает отчёты об ошибках по этому поводу, мы немного подробнее остановимся здесь.

SciPy сообщает о своей зависимости от NumPy через pyproject.toml для целей сборки, и SciPy также имеет проверку во время выполнения, что доступна подходящая версия NumPy. SciPy больше не использует setup_requires (что в прошлом вызывало easy_install); зависимости сборки теперь обрабатываются только через pyproject.toml. pyproject.toml основывается на PEP 517; pip имеет --no-use-pep517 и --no-build-isolation флаги, которые могут игнорировать pyproject.toml или обрабатывать его иначе - если пользователи используют эти флаги, они сами отвечают за установку правильных зависимостей сборки.

Диапазоны версий для NumPy и других зависимостей#

Для зависимостей важно установить нижние и верхние границы их версий. Для время сборки зависимости, они указаны в pyproject.toml и версии будут only применяются к сборке SciPy. Можно указать либо диапазон, либо конкретную версию для зависимости, такой как meson-python или pybind11. Для NumPy нам также нужно беспокоиться о совместимости ABI. Однако, с NumPy >=2.0.0rc1 обратная совместимость гарантируется вплоть до NumPy 1.19 серии, поэтому указание минимальной поддерживаемой версии NumPy во время сборки больше не требуется в pyproject.toml.

Для зависимости времени выполнения (в настоящее время только numpy), мы указываем диапазон версий в pyproject.toml и в scipy/__init__.py. Определение верхней границы немного сложно. Если мы не установим никакой границы, через несколько лет будет установлена слишком новая версия, и NumPy может к тому времени объявить устаревшими и удалить некоторые API, от которых зависит SciPy. С другой стороны, если мы установим верхнюю границу на самую новую уже выпущенную версию, то как только будет выпущена новая версия NumPy, не будет подходящей версии SciPy, которая работает с ней. Учитывая, что NumPy и SciPy выпускают релизы каждые 6 месяцев и что функции, объявленные устаревшими в NumPy, должны оставаться еще в двух релизах, мы указываем верхнюю границу как <2.xx+3.0 (где xx является минорной версией последнего уже выпущенного NumPy).

Поддерживаемые версии Python и NumPy#

The Python версии, которые поддерживает SciPy, перечислены в списке классификаторов PyPI в pyproject.toml, и упомянуто в примечаниях к выпуску для каждого релиза. Все новые выпуски Python будут поддерживаться как можно скорее. Общую политику по прекращению поддержки версий Python или NumPy см. в NEP 29. Окончательное решение о прекращении поддержки всегда принимается на форуме scipy-dev.

Минимальная поддерживаемая NumPy версия для версии SciPy упоминается в примечаниях к выпуску и закодирована в pyproject.toml и scipy/__init__.py. Обычно последний выпуск SciPy поддерживает ~5-7 минорных версий NumPy: до версий NumPy возрастом до 2,5 лет, (учитывая, что частота выпусков NumPy составляет около 2 раз в год на момент написания) плюс две версии в будущем.

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

Создание бинарных установщиков#

Примечание

Этот раздел только о создании бинарных установщиков SciPy для распределять. Информацию о сборке SciPy на той же машине, где она будет использоваться, см. в Сборка из исходного кода.

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

Общее

  • Бинарный файл специфичен для одной (основной) версии Python (поскольку разные основные версии Python не совместимы по ABI, по крайней мере до Python 3.12).

  • Сборка против NumPy 2.0.0, тогда он будет работать для всех версий NumPy с тем же основным номером версии (NumPy поддерживает обратную совместимость ABI), и настолько далеко назад, как NumPy 1.19 серия на момент написания.

  • Самый простой доступный инструментарий для создания переносимых бинарных файлов SciPy — это наш cibuildwheel инфраструктура для общих платформ, с подробностями, доступными в коде нашей CI инфраструктуры и доступными через cibuildwheel команда в Windows, Linux и MacOS, хотя с некоторыми дополнительными внешними зависимостями, требуемыми в некоторых случаях

Windows

  • Для 64-битных установщиков Windows, собранных с помощью свободного инструментария, используйте метод, документированный на numpy/numpy. Этот метод, вероятно, будет использоваться для самого SciPy, как только станет ясно, что поддержка этого инструментария устойчива в долгосрочной перспективе. См. MingwPy проект и эту ветку обсуждения для подробностей.

  • Другой способ создания 64-битных установщиков для Windows — с помощью icc, ifort плюс MKL (или MSVC вместо icc). Для инструкций по инструментарию Intel см. этой статьёй и для (частичных) инструкций MSVC см. эта вики-страница.

  • В более ранних выпусках SciPy содержался установщик .exe «superpack». Они включают 3 полные сборки (без SSE, SSE2, SSE3) и были собраны с numpy/numpy-vendor. Эта настройка сборки, как известно, больше не работает хорошо и больше не поддерживается. Она использовала g77 вместо gfortran из-за проблем с распространением сложных DLL (см. gh-2829). Поскольку инструментарий больше не поддерживается, поддержка g77 больше не нужна, и SciPy теперь может включать код на Fortran 90/95.

Linux

  • Совместимые с PyPI Linux-колеса могут быть созданы через manylinux проект, который используется внутри нашего cibuildwheel инфраструктура.

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

Интерактивные примеры в строках документации#

Примеры в строках документации можно сделать интерактивными с помощью расширение jupyterlite-sphinx, который реализует .. try_examples:: директива. При использовании в разделе "Примеры" документации эта директива создаст кнопку, позволяющую пользователям открыть пример в интерактивном окне JupyterLite или в новой вкладке как блокнот Jupyter. Для SciPy эта директива автоматически добавляется ко всей документации с разделом "Примеры" через global_enable_try_examples параметр конфигурации в doc/source/conf.py.

Чтобы скрыть кнопки, превращающие примеры из документации во встроенные блокноты, после сборки HTML-документации отредактируйте try_examples.json файл конфигурации времени выполнения после scipy/doc/build/html/ и добавить пути URL файлов, которые нужно игнорировать, к ignore_patterns список. Этот список ожидает элементы в виде шаблонов регулярных выражений JavaScript. Исходная версия этого файла в чистой сборке документации

{
    "global_min_height": "400px",
    "ignore_patterns": [".*"]
}

Кнопки для преобразования разделов с примерами во встроенные интерактивные блокноты скрыты по умолчанию в чистых сборках документации.

См. документацию для jupyterlite-sphinx Директива TryExamples для получения дополнительной информации.

Создание релиза SciPy#

На высшем уровне вот что делает менеджер выпуска для публикации новой версии SciPy:

  1. Предложите график выпуска на форуме SciPy по адресу https://discuss.scientific-python.org/.

  2. Создать ветку обслуживания для выпуска.

  3. Пометить релиз.

  4. Собрать все артефакты выпуска (исходники, установщики, документация).

  5. Загрузить артефакты релиза.

  6. Анонсировать выпуск.

  7. Перенести соответствующие изменения в примечания к выпуску и скрипты сборки в основную ветку.

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

Предложение графика выпуска#

Типичный цикл выпуска выглядит так:

  • Создать ветку обслуживания

  • Выпустить бета-версию

  • Выпустить "релиз-кандидат" (RC)

  • При необходимости выпустить один или несколько новых RC

  • Выпустить финальную версию, как только не останется проблем с последним релиз-кандидатом

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

В идеале финальный релиз идентичен последнему RC, однако могут быть незначительные различия — решение о риске принимает менеджер релиза. Обычно, если изменяется скомпилированный код или сложный чистый Python-код, требуется новый RC, в то время как простой исправление ошибки, перенесённое из основной ветки, не требует нового RC.

Чтобы предложить расписание, отправьте список с предполагаемыми датами для ветвления и бета/rc/финальных релизов на форум SciPy по адресу https://discuss.scientific-python.org/. В том же сообщении попросите всех проверить, есть ли важные проблемы/PR, которые нужно включить, но не помечены вехой для релиза или меткой "backport-candidate".

Создание ветки обслуживания#

Перед ветвлением убедитесь, что заметки о выпуске обновлены насколько это возможно. Включите вывод tools/gh_lists.py и tools/authors.py в примечаниях к выпуску.

Ветки обслуживания называются maintenance/..x (например, 0.19.x). Чтобы создать его, просто отправьте ветку с правильным именем в репозиторий scipy. Сразу после этого отправьте коммит, в котором вы увеличиваете номер версии в основной ветке и добавляете заметки о выпуске для этой новой версии. Отправьте электронное письмо на форум SciPy по адресу https://discuss.scientific-python.org/ чтобы сообщить людям, что вы это сделали.

Обновление переключателя версий#

Выпадающий список переключения версий необходимо обновить информацией о новом релизе на main только в ветке.

  • doc/source/_static/version_switcher.json: добавить новый релиз, новую версию разработки и передать "preferred": true от старого релиза к новому релизу.

Обновление верхних границ зависимостей#

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

  • pyproject.toml: все зависимости времени сборки, а также поддерживаемые Python

    и версии NumPy

  • scipy/__init__.py: для проверки версии NumPy

Каждый файл содержит комментарии, описывающие, как установить правильные верхние границы.

Тегирование релиза#

Сначала убедитесь, что вы правильно настроили GPG. См. scipy/scipy#4919 для обсуждения подписания тегов релиза, и https://keyring.debian.org/creating-key.html для инструкций по созданию GPG-ключа, если у вас его нет. Обратите внимание, что на некоторых платформах может быть более подходящим использовать gpg2 вместо gpg так что пароли могут храниться с помощью gpg-agent как обсуждалось в scipy/scipy#10189. При подготовке релиза удалённо может потребоваться установить pinentry-mode loopback в ~/.gnupg/gpg-agent.conf потому что использование gpg2 в противном случае продолжится через недоступный графический парольный запрос.

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

gpg --send-keys <yourkeyid>

Проверьте, что все соответствующие коммиты находятся в ветке. В частности, проверьте issues и PRs в рамках Milestone для релиза (scipy/scipy), PR с меткой “backport-candidate”, и что примечания к выпуску актуальны и включены в html-документацию.

Затем обновите version в pyproject.toml и зафиксировать изменение с сообщением типа REL: set version to . Не отправляйте этот коммит в репозиторий SciPy пока.

Наконец, локально пометьте релиз тегом git tag -s (the -s гарантирует, что тег подписан). Если gpg2 предпочтительнее, тогда git config --global gpg.program gpg2 может быть уместным. Продолжите с созданием артефактов релиза (следующий раздел). Только отправьте коммит релиза в репозиторий scipy после успешного создания sdists и документации. Затем продолжите с созданием колес. Только отправьте тег релиза в репозиторий после успешного создания всех колес на TravisCI и Appveyor (если произойдёт сбой, вам придётся переместить тег, что является плохой практикой). Наконец, после отправки тега также отправьте второй коммит, который увеличивает номер версии и добавляет .dev0 для version: и устанавливает ISRELEASED в False снова. Это также относится к новым кандидатам в релизы и для удаления rc аффикс при переходе от кандидата на выпуск к официальному выпуску.

Создание артефактов выпуска#

Вот полный список артефактов, созданных для выпуска:

  • sdist (scipy-x.y.y.tar.gz, как для PyPI, так и для GitHub Releases)

  • Бинарные сборки для Windows, Linux и macOS

  • Документация (html)

  • A README.txt файл

  • A Changelog файл

An sdist генерируется запуском python -m build --sdist (примечание: нам всё ещё нужно перенести это в задание CI!), а журнал изменений и README создаются запуском python dev.py notes (с тегами, см. python dev.py notes --help) в корне репозитория и окажутся в REPO_ROOT/release/. Сделайте это после того, как создали подписанный тег локально. Если это завершается без проблем, отправьте коммит релиза (не тег, см. раздел выше) в репозиторий scipy.

Для сборки колес, отправьте коммит, содержащий текст [wheel build] в ветку, используемую для текущего релиза. Это запускает cibuildwheel собирает для всех необходимых версий Python и платформ. Соответствующие версионные ограничения для NumPy и других зависимостей должны были быть обновлены в pyproject.toml сразу после ветвления. Если сборка колес выявит проблемы, которые нужно исправить с помощью обратных портов на ветке обслуживания, вы можете удалить локальные теги (например, git tag -d v1.2.0rc1) и перезапустить с тегированием выше на новом кандидатном коммите.

The cibuildwheel инфраструктура запускает тесты из собранных колес, и если они проходят, загружает колеса в https://anaconda.org/multibuild-wheels-staging/scipy.

Оттуда вы можете скачать их для загрузки в PyPI. Это можно сделать автоматически с помощью tools/download-wheels.py:

$ python tools/download-wheels.py 1.5.0rc1 -w REPO_ROOT/release/installers

После этого мы хотим перегенерировать файл README, чтобы иметь MD5 и SHA256 контрольные суммы только что загруженных колес в нем. Запустите python dev.py notes снова.

Загрузка артефактов выпуска#

Для релиза в настоящее время существует пять мест в сети для загрузки файлов:

  • PyPI (sdist, wheels)

  • GitHub Releases (sdist, release notes, Changelog)

  • scipy.org (анонс выпуска)

  • docs.scipy.org (HTML-документация)

PyPI:

Сначала загрузите wheels, а затем sdist:

twine upload REPO_ROOT/release/installers/*.whl
twine upload REPO_ROOT/release/installers/scipy-1.x.y.tar.gz

Релизы на Github:

Использовать GUI на scipy/scipy для создания релиза и загрузки всех артефактов релиза. На этом этапе уместно отправить тег и связать новый релиз (кандидат) с этим тегом в графическом интерфейсе. Например, git push upstream v1.2.0rc1, где upstream представляет scipy/scipy. Полезно проверить предыдущий релиз, чтобы точно определить, какие артефакты должны быть включены в процесс загрузки через GUI. Также обратите внимание, что примечания к выпуску не заполняются автоматически в описание релиза на GitHub, и некоторая ручная переформатировка в markdown может быть весьма полезной для соответствия форматированию предыдущих релизов на сайте. Обычно мы не включаем списки Issue и Pull Request в эти описания GUI.

scipy.org:

Исходный код сайта находится в scipy/scipy.org. Обновить раздел Новости в content/en/news.md через PR. Это только для официальных релизов, а не для кандидатов в релизы.

docs.scipy.org:

Сначала соберите документацию scipy, запустив make dist в scipy/doc/. Убедитесь, что они выглядят нормально, затем загрузите их на сервер документации с make upload USERNAME=rgommers RELEASE=0.19.0. Обратите внимание, что для доступа к серверу документации требуется SSH; спросите @pv (администратор сервера), @tylerjereddy или @rgommers (могут загружать), если у вас его нет.

Исходный код самого веб-сайта поддерживается в scipy/docs.scipy.org. Добавить новую версию SciPy в таблицу релизов в index.rst. Отправьте этот коммит, затем выполните make upload USERNAME=yourusername. Это относится только к официальным релизам, а не к кандидатам на релиз.

Примечание

Переключатель версий в развернутой документации не будет считать новый релиз стабильным, пока изменения в version_switcher.json были объединены в main ветка (см. gh-22305). Следовательно, перенос заметок о выпуске и изменений переключателя версий в main в идеале должно выполняться одновременно с развертыванием документации для нового релиза.

Завершение#

Отправить сообщение с объявлением о выпуске https://discuss.scientific-python.org/c/announcements/.

Для бета- и rc-версий попросите людей протестировать (запустить тесты scipy и протестировать на своем коде) и сообщить о проблемах на Github или Discourse.

После окончательного релиза перенести соответствующие изменения в примечания к выпуску, скрипты сборки, сопоставление имен авторов в tools/authors.py и любые другие изменения, которые были сделаны только в ветке обслуживания для main.

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

$ ssh your-username@docs.scipy.org
$ cd /srv/docs_scipy_org/doc/scipy-1.13.1
$ vim try_examples.json  # edit the ignore list to remove: ".*"