Советы и хитрости разработчиков#
Советы по повышению продуктивности и сохранению рассудка#
В этом разделе мы собрали некоторые полезные советы и инструменты, которые могут улучшить качество вашей жизни при проверке pull-запросов, запуске модульных тестов и т.д. Некоторые из этих трюков состоят из пользовательских скриптов, требующих расширения браузера, такого как TamperMonkey или GreaseMonkey; для настройки пользовательских скриптов у вас должно быть одно из этих расширений, установленное, включенное и работающее. Мы предоставляем пользовательские скрипты как GitHub gists; чтобы установить их, нажмите кнопку "Raw" на странице gist.
Свёртывание и развёртывание устаревших диффов в pull requests#
GitHub скрывает обсуждения в PR, когда соответствующие строки кода были изменены в промежутке. Это userscript предоставляет сочетание клавиш (на момент написания Control-Alt-P, но проверьте код, чтобы убедиться) для развертывания всех скрытых обсуждений сразу, чтобы вы могли наверстать упущенное.
Проверка pull requests как удаленных отслеживаемых веток#
В вашей локальной копии добавьте в ваш .git/config, под [remote
"upstream"] заголовок, строка:
fetch = +refs/pull/*/head:refs/remotes/upstream/pr/*
Вы можете затем использовать git checkout pr/PR_NUMBER для перехода к коду пул-реквеста с заданным номером. (Подробнее в этом гисте.)
Отображение покрытия кода в pull requests#
Чтобы наложить отчеты о покрытии кода, сгенерированные непрерывной интеграцией CodeCov, рассмотрите это расширение браузера. Покрытие каждой строки будет отображаться цветным фоном за номером строки.
Полезные псевдонимы и флаги pytest#
Полный набор тестов выполняется довольно долго. Для более быстрых итераций можно выбрать подмножество тестов с помощью селекторов pytest. В частности, можно запустить одиночный тест на основе его идентификатора узла:
pytest -v sklearn/linear_model/tests/test_logistic.py::test_sparsify
или используйте -k параметр pytest для выбора тестов на основе их названия. Например:
pytest sklearn/tests/test_common.py -v -k LogisticRegression
будет запускать все общие тесты для LogisticRegression оценщик.
Когда модульный тест завершается неудачей, следующие приёмы могут облегчить отладку:
Аргумент командной строки
pytest -lуказывает pytest выводить локальные переменные при возникновении сбоя.Аргумент
pytest --pdbпереходит в отладчик Python при сбое. Чтобы вместо этого перейти в расширенный отладчик IPythonipdb, вы можете настроить псевдоним оболочки для:pytest --pdbcls=IPython.terminal.debugger:TerminalPdb --capture no
Другие pytest опции, которые могут стать полезными, включают:
-xкоторый завершается при первом неудачном тесте,--lfперезапустить тесты, которые не прошли в предыдущем запуске,--ffперезапустить все предыдущие тесты, запустив сначала те, которые завершились неудачей,-sчтобы pytest не перехватывал выводprint()утверждения,--tb=shortили--tb=lineдля управления длиной логов,--runxfailтакже запускает тесты, отмеченные как известные неудачи (XFAIL), и сообщает об ошибках.
Поскольку наши тесты непрерывной интеграции будут выдавать ошибку, если
FutureWarning не перехватывается должным образом, также рекомендуется запустить pytest вместе с
-Werror::FutureWarning флаг.
Стандартные ответы для рецензирования#
Может быть полезно хранить некоторые из них в сохраненные ответы для проверки:
Проблема: Вопросы по использованию
You are asking a usage question. The issue tracker is for bugs and new features. For usage questions, it is recommended to try [Stack Overflow](https://stackoverflow.com/questions/tagged/scikit-learn) or [the Mailing List](https://mail.python.org/mailman/listinfo/scikit-learn).
Unfortunately, we need to close this issue as this issue tracker is a communication tool used for the development of scikit-learn. The additional activity created by usage questions crowds it too much and impedes this development. The conversation can continue here, however there is no guarantee that it will receive attention from core developers.
Проблема: Вы можете обновить документацию
Please feel free to offer a pull request updating the documentation if you feel it could be improved.
Проблема: Самодостаточный пример для ошибки
Please provide [self-contained example code](https://scikit-learn.org/dev/developers/minimal_reproducer.html), including imports and data (if possible), so that other contributors can just run it and reproduce your issue. Ideally your example code should be minimal.
Проблема: Версии программного обеспечения
To help diagnose your issue, please paste the output of:
```py
import sklearn; sklearn.show_versions()
```
Thanks.
Проблема: Блоки кода
Readability can be greatly improved if you [format](https://help.github.com/articles/creating-and-highlighting-code-blocks/) your code snippets and complete error messages appropriately. For example:
```python
print(something)
```
generates:
```python
print(something)
```
And:
```pytb
Traceback (most recent call last):
File "", line 1, in
ImportError: No module named 'hello'
```
generates:
```pytb
Traceback (most recent call last):
File "", line 1, in
ImportError: No module named 'hello'
```
You can edit your issue descriptions and comments at any time to improve readability. This helps maintainers a lot. Thanks!
Проблема/Комментарий: Ссылка на код
Friendly advice: for clarity's sake, you can link to code like [this](https://help.github.com/articles/creating-a-permanent-link-to-a-code-snippet/).
Issue/Comment: Ссылка на комментарии
Please use links to comments, which make it a lot easier to see what you are referring to, rather than just linking to the issue. See [this](https://stackoverflow.com/questions/25163598/how-do-i-reference-a-specific-issue-comment-on-github) for more details.
PR-NEW: Улучшенное описание и заголовок
Thanks for the pull request! Please make the title of the PR more descriptive. The title will become the commit message when this is merged. You should state what issue (or PR) it fixes/resolves in the description using the syntax described [here](https://scikit-learn.org/dev/developers/contributing.html#contributing-pull-requests).
PR-NEW: Исправление #
Please use "Fix #issueNumber" in your PR description (and you can do it more than once). This way the associated issue gets closed automatically when the PR is merged. For more details, look at [this](https://github.com/blog/1506-closing-issues-via-pull-requests).
PR-NEW или Issue: Стоимость обслуживания
Every feature we include has a [maintenance cost](https://scikit-learn.org/dev/faq.html#why-are-you-so-selective-on-what-algorithms-you-include-in-scikit-learn). Our maintainers are mostly volunteers. For a new feature to be included, we need evidence that it is often useful and, ideally, [well-established](https://scikit-learn.org/dev/faq.html#what-are-the-inclusion-criteria-for-new-algorithms) in the literature or in practice. Also, we expect PR authors to take part in the maintenance for the code they submit, at least initially. That doesn't stop you implementing it for yourself and publishing it in a separate repository, or even [scikit-learn-contrib](https://scikit-learn-contrib.github.io).
PR-WIP: Что нужно перед слиянием?
Please clarify (perhaps as a TODO list in the PR description) what work you believe still needs to be done before it can be reviewed for merge. When it is ready, please prefix the PR title with `[MRG]`.
PR-WIP: Необходим регрессионный тест
Please add a [non-regression test](https://en.wikipedia.org/wiki/Non-regression_testing) that would fail at main but pass in this PR.
PR-MRG: Терпение
Before merging, we generally require two core developers to agree that your pull request is desirable and ready. [Please be patient](https://scikit-learn.org/dev/faq.html#why-is-my-pull-request-not-getting-any-attention), as we mostly rely on volunteered time from busy core developers. (You are also welcome to help us out with [reviewing other PRs](https://scikit-learn.org/dev/developers/contributing.html#code-review-guidelines).)
PR-MRG: Добавить в новое
Please add an entry to the future changelog by adding an RST fragment into the module associated with your change located in `doc/whats_new/upcoming_changes`. Refer to the following [README](https://github.com/scikit-learn/scikit-learn/blob/main/doc/whats_new/upcoming_changes/README.md) for full instructions.
PR: Не изменять несвязанное
Please do not change unrelated lines. It makes your contribution harder to review and may introduce merge conflicts to other pull requests.
Отладка проблем CI#
Проблемы с CI могут возникать по разным причинам, поэтому это ни в коем случае не исчерпывающее руководство, а скорее список полезных советов и приёмов.
Использование lock-файла для получения среды, близкой к CI#
conda-lock можно использовать для создания conda-окружения с точно такими же
conda- и pip-пакетами, как на CI. Например, следующая команда
создаст conda-окружение с именем scikit-learn-doc которая похожа на доверительный интервал:
conda-lock install -n scikit-learn-doc build_tools/circle/doc_linux-64_conda.lock
Примечание
Это работает только если у вас та же ОС, что и в сборке CI (проверьте platform: в lock-файле). Например, предыдущая команда будет работать только если вы находитесь на машине с Linux. Также это может не позволить воспроизвести некоторые проблемы, которые больше связаны с особенностями среды CI, например, архитектура процессора, сообщаемая OpenBLAS в sklearn.show_versions().
Если у вас нет той же ОС, что и в сборке CI, вы все равно можете создать conda-окружение из соответствующего yaml-файла окружения, хотя оно не будет таким же близким, как CI-окружение при использовании связанного lock-файла. Например, для сборки документации:
conda env create -n scikit-learn-doc -f build_tools/circle/doc_environment.yml -y
Это может не дать вам точно таких же версий пакетов, как в CI, по различным причинам, например:
некоторые пакеты могли иметь новые выпуски между моментом последнего обновления файлов блокировки в
mainветка и время, когда вы запускаетеconda createкоманде. Вы всегда можете попробовать посмотреть версию в lock-файле и указать версии вручную для некоторых конкретных пакетов, которые, по вашему мнению, помогут воспроизвести проблему.различные пакеты могут быть установлены по умолчанию в зависимости от ОС. Например, библиотека BLAS по умолчанию при установке numpy — это OpenBLAS на Linux и MKL на Windows.
Также проблема может быть специфичной для ОС, поэтому единственный способ воспроизвести — иметь ту же ОС, что и в сборке CI.
Отладка ошибок памяти в Cython с помощью valgrind#
Хотя встроенное управление памятью в python/numpy относительно надежно, оно может привести к снижению производительности для некоторых процедур. По этой причине большая часть высокопроизводительного кода в scikit-learn написана на cython. Однако этот прирост производительности имеет компромисс: ошибки памяти могут легко возникать в коде на cython, особенно в ситуациях, когда этот код сильно зависит от арифметики указателей.
Ошибки памяти могут проявляться по-разному. Самые простые для отладки часто — это ошибки сегментации и связанные с ними ошибки glibc. Неинициализированные переменные могут привести к неожиданному поведению, которое трудно отследить. Очень полезным инструментом при отладке таких ошибок является valgrind.
Valgrind — это инструмент командной строки, который может отслеживать ошибки памяти в различных типах кода. Следуйте этим шагам:
Установить valgrind в вашей системе.
Скачать файл подавления valgrind для Python: API scikit-learn предоставляет множество функций и методов, которые имеют много входных параметров. Например, до этого выпуска можно было создать экземпляр.
Следуйте инструкциям в README.valgrind файл для настройки ваших подавлений python. Если вы этого не сделаете, у вас будут появляться ложные выводы, связанные с интерпретатором python, а не с вашим собственным кодом.
Запустите valgrind следующим образом:
valgrind -v --suppressions=valgrind-python.supp python my_test_script.py
Результатом будет список всех ошибок, связанных с памятью, которые ссылаются на строки в C-коде, сгенерированном cython из вашего .pyx файла. Если вы изучите указанные строки в .c файле, вы увидите комментарии, указывающие на соответствующее место в вашем исходном .pyx файле. Надеемся, что вывод даст вам подсказки относительно источника ошибки памяти.
Для получения дополнительной информации о valgrind и наборе его опций см. учебные пособия и документацию на сайт valgrind.
Сборка и тестирование для платформы ARM64 на машине x86_64#
Машины на базе ARM являются популярной целью для мобильных, периферийных или других развертываний с низким энергопотреблением (включая облачные, например, на Scaleway или AWS Graviton).
Вот инструкции по настройке локальной среды разработки для воспроизведения ошибок, специфичных для ARM, или сбоев тестов на хост-ноутбуке или рабочей станции x86_64. Это основано на эмуляции пользовательского режима QEMU с использованием docker для удобства (см. multiarch/qemu-user-static).
Примечание
Следующие инструкции приведены для ARM64, но они также применимы к ppc64le после соответствующего изменения путей Docker-образа и Miniforge.
Подготовьте папку в файловой системе хоста и загрузите необходимые инструменты и исходный код:
mkdir arm64
pushd arm64
wget https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-Linux-aarch64.sh
git clone https://github.com/scikit-learn/scikit-learn.git
Используйте docker для установки QEMU в пользовательском режиме и запуска контейнера ARM64v8 с доступом к вашей общей папке под /io mount point:
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
docker run -v `pwd`:/io --rm -it arm64v8/ubuntu /bin/bash
В контейнере установите miniforge3 для архитектуры ARM64 (также известной как aarch64):
bash Miniforge3-Linux-aarch64.sh
# Choose to install miniforge3 under: `/io/miniforge3`
При каждом перезапуске нового контейнера вам потребуется повторно инициализировать окружение conda,
ранее установленное в /io/miniforge3:
/io/miniforge3/bin/conda init
source /root/.bashrc
как /root домашняя папка является частью эфемерного docker-контейнера. Каждый файл или каталог, хранящийся под /io с другой стороны, является устойчивым.
Затем вы можете собрать scikit-learn как обычно (вам потребуется установить инструменты компилятора
и зависимости с помощью apt или conda как обычно). Сборка scikit-learn
занимает много времени из-за слоя эмуляции, однако это нужно сделать
только один раз, если вы поместите папку scikit-learn в /io точка монтирования.
Затем используйте pytest для запуска только тестов модуля, который вас интересует при отладке.
Сборка Meson Backend#
Начиная с scikit-learn 1.5.0 мы используем meson-python в качестве инструмента сборки. Meson — это новый инструмент для scikit-learn и экосистемы PyData. Он используется несколькими другими пакетами, которые написали хорошие руководства о том, что это такое и как работает.
документация по настройке pandas: pandas имеет аналогичную настройку, как у нас (без spin или dev.py)
документация scipy Meson даёт больше информации о том, как Meson работает за кулисами