Настройка и использование вашей среды разработки#

Использование виртуальных окружений#

Часто задаваемый вопрос: "Как настроить версию NumPy для разработки параллельно с выпущенной версией, которую я использую для работы/исследований?".

Один простой способ достичь этого — установить выпущенную версию в site-packages, используя, например, pip или conda, и настроить версию для разработки в виртуальном окружении.

Если вы используете conda, мы рекомендуем создать отдельную виртуальную среду для разработки numpy с помощью environment.yml файл в корне репозитория (это создаст окружение и установит все зависимости для разработки одновременно):

$ conda env create -f environment.yml  # `mamba` works too for this command
$ conda activate numpy-dev

Если вы установили Python каким-либо другим способом, кроме conda, сначала установите virtualenv (опционально использовать virtualenvwrapper), затем создайте ваш виртуальный env (названный numpy-dev здесь), активируйте его и установите все зависимости проекта с помощью:

$ virtualenv numpy-dev
$ source numpy-dev/bin/activate # activate virtual environment
$ python -m pip install -r requirements/all_requirements.txt

Теперь, когда вы хотите переключиться на виртуальное окружение, вы можете использовать команду source numpy-dev/bin/activate, и deactivate для выхода из виртуального окружения и возврата к предыдущей оболочке.

Сборка из исходного кода#

См. Сборка из исходного кода.

Тестирование сборок#

Перед запуском тестов сначала установите зависимости для тестов:

$ python -m pip install -r requirements/test_requirements.txt
$ python -m pip install asv # only for running benchmarks

Для сборки версии NumPy для разработки и запуска тестов, создания интерактивных оболочек с правильно настроенными путями импорта Python и т.д., используйте spin утилиты. Для запуска тестов выполните одно из следующих действий:

$ spin test -v
$ spin test numpy/random  # to run the tests in a specific module
$ spin test -v -t numpy/_core/tests/test_nditer.py::test_iter_c_order
$ spin test -p auto # to run tests in parallel threads using pytest-run-parallel

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

Вы также можете использовать spin bench для тестирования производительности. См. spin --help для дополнительных параметров командной строки.

Примечание

Если вышеуказанные команды приводят к RuntimeError: Cannot parse version 0+untagged.xxxxx, запустить git pull upstream main --tags.

Дополнительные аргументы могут быть переданы в pytest передавая дополнительные аргументы после голого --. Например, чтобы запустить тестовый метод с --pdb флаг, переданный цели, выполните следующее:

$ spin test -t numpy/tests/test_scripts.py::test_f2py -- --pdb

Вы также можете сопоставлять имена тестов с использованием операторов Python передав -k аргумент для pytest:

$ spin test -v -t numpy/_core/tests/test_multiarray.py -- -k "MatMul and not vector"

Для запуска "doctests" – проверки корректности примеров кода в документации – используйте check-docs команда spin. Она полагается на scipy-docs пакет, который предоставляет несколько дополнительных возможностей поверх стандартной библиотеки doctest пакет. Установите scipy-doctest и запустить одну из:

$ spin check-docs -v
$ spin check-docs numpy/linalg
$ spin check-docs -v -- -k 'det and not slogdet'

Примечание

Помните, что все тесты NumPy должны проходить перед коммитом ваших изменений.

Примечание

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

Другие опции сборки#

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

Запуск тестов#

Помимо использования spin, есть различные способы запуска тестов. Внутри интерпретатора тесты можно запускать так:

>>> np.test()  
>>> np.test('full')   # Also run tests marked as slow
>>> np.test('full', verbose=2)   # Additionally print test name/file

An example of a successful test :
``4686 passed, 362 skipped, 9 xfailed, 5 warnings in 213.99 seconds``

Или аналогичным способом из командной строки:

$ python -c "import numpy as np; np.test()"

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

Запуск отдельных тестовых файлов может быть полезен; это намного быстрее, чем запуск всего набора тестов или всего модуля (пример: np.random.test()). Это можно сделать с помощью:

$ python path_to_testfile/test_file.py

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

Запуск тестов с tox также поддерживается. Например, чтобы собрать NumPy и запустить набор тестов с Python 3.9, используйте:

$ tox -e py39

Для получения более подробной информации см. Рекомендации по тестированию.

Примечание: не запускайте тесты из корневой директории вашего numpy git репозитория без spin, что приведет к странным ошибкам тестирования.

Выполнение проверок типов#

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

$ spin mypy

Это будет искать в typing/tests каталог для наборов операций для проверки на несовместимость типов.

Запуск линтинга#

Проверки линтера могут выполняться для недавно добавленных строк кода Python.

Установите все зависимые пакеты с помощью pip:

$ python -m pip install -r requirements/linter_requirements.txt

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

$ python tools/linter.py

Чтобы проверить все изменения в новом коде Python текущей ветки с целевой веткой, выполните:

$ python tools/linter.py

Если ошибок нет, скрипт завершается без сообщения. В случае ошибок проверьте сообщение об ошибке для получения подробностей:

$ python tools/linter.py
./numpy/_core/tests/test_scalarmath.py:34:5: E303 too many blank lines (3)
1       E303 too many blank lines (3)

Рекомендуется запускать проверки линтера перед отправкой коммитов в удалённую ветку, поскольку линтер выполняется как часть конвейера CI.

Для получения дополнительных сведений о руководствах по стилю:

Пересборка и очистка рабочего пространства#

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

$ git clean -xdf

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

$ git checkout .
$ git reset --hard

Отладка#

Еще один часто задаваемый вопрос: "Как отлаживать C-код внутри NumPy?". Сначала убедитесь, что у вас установлен gdb с расширениями Python (часто по умолчанию в Linux). Вы можете проверить, какая версия Python запущена внутри gdb, чтобы убедиться в правильности настройки:

(gdb) python
>import sys
>print(sys.version_info)
>end
sys.version_info(major=3, minor=7, micro=0, releaselevel='final', serial=0)

Большинство сборок Python не включают отладочные символы и собраны с включёнными оптимизациями компилятора. Для получения наилучшего опыта отладки рекомендуется использовать отладочную сборку Python, см. Возвращает индексы первых вхождений максимальных значений вдоль указанной оси. Если ось равна None, индекс соответствует выровненной матрице..

В плане отладки, NumPy также должен быть собран в режиме отладки. Вам нужно использовать debug тип сборки и отключение оптимизаций, чтобы убедиться -O0 флаг используется во время сборки объекта. Обратите внимание, что NumPy НЕ должен быть установлен в вашей среде перед сборкой с spin build команда.

Для генерации отладочной информации на уровне исходного кода в процессе сборки выполните:

$ spin build --clean -- -Dbuildtype=debug -Ddisable-optimization=true

Примечание

Если вы используете окружение conda, учтите, что conda устанавливает CFLAGS и CXXFLAGS автоматически, и они будут включать -O2 флаг по умолчанию. Вы можете безопасно использовать unset CFLAGS && unset CXXFLAGS чтобы избежать их или предоставить их в начале spin команда: CFLAGS="-O0 -g" CXXFLAGS="-O0 -g". Альтернативно, чтобы более постоянно контролировать эти переменные, вы можете создать env_vars.sh файл в /numpy-dev/etc/conda/activate.d каталог. В этом файле вы можете экспортировать CFLAGS и CXXFLAGS переменные. Полные инструкции см. в https://conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html#saving-environment-variables.

Далее вам нужно написать скрипт на Python, который вызывает C-код, выполнение которого вы хотите отладить. Например, mytest.py:

import numpy as np
x = np.arange(5)
np.empty_like(x)

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

$ spin gdb /path/to/mytest.py

В случае, если вы используете инструментарий clang:

$ spin lldb /path/to/mytest.py

А затем в отладчике:

(gdb) break array_empty_like
(gdb) run

аналог в lldb:

(lldb) breakpoint set --name array_empty_like
(lldb) run

Выполнение теперь остановится на соответствующей функции C, и вы можете пошагово пройти через неё как обычно. Доступен ряд полезных команд, специфичных для Python. Например, чтобы увидеть, где в коде Python вы находитесь, используйте py-list, чтобы увидеть трассировку Python, используйте py-bt. Для получения дополнительных сведений см. DebuggingWithGdb. Вот некоторые часто используемые команды:

  • list: Указать конкретную функцию или строку.

  • next: Шаг программы, выполняемый через вызовы подпрограмм.

  • step: Продолжить отлаживаемую программу после сигнала или точки останова.

  • print: Вывести значение выражения EXP.

Богатая поддержка отладки Python требует, чтобы python-gdb.py скрипт, распространяемый с Python, установлен в пути, где gdb может его найти. Если вы установили сборку Python из менеджера пакетов вашей системы, вам, вероятно, не нужно ничего делать вручную. Однако если вы собрали Python из исходников, вам, скорее всего, потребуется создать .gdbinit файл в вашем домашнем каталоге, указывающий gdb на местоположение вашей установки Python. Например, версия python, установленная через pyenv нуждается в .gdbinit файл со следующим содержимым:

add-auto-load-safe-path ~/.pyenv

Сборка NumPy с Python, собранным с поддержкой отладки (в дистрибутивах Linux обычно упакован как python-dbg) настоятельно рекомендуется.

Понимание кода и начало работы#

Лучшая стратегия для лучшего понимания кодовой базы — выбрать что-то, что вы хотите изменить, и начать читать код, чтобы понять, как он работает. Если сомневаетесь, вы можете задать вопросы в списке рассылки. Совершенно нормально, если ваши pull requests не идеальны, сообщество всегда готово помочь. Как волонтерский проект, иногда что-то может быть упущено, и совершенно нормально напомнить нам, если что-то осталось без ответа около двух-четырех недель.

Так что смело выбирайте что-то, что раздражает или сбивает с толку в NumPy, экспериментируйте с кодом, участвуйте в обсуждениях или изучайте справочные документы, чтобы попытаться это исправить. Все встанет на свои места, и вскоре у вас будет довольно хорошее понимание проекта в целом. Удачи!