Проверка ошибок и исправлений ошибок в NumPy#

В этом руководстве вы узнаете, как:

  • Проверить наличие ошибки в NumPy

  • Проверить исправление, если оно было сделано для ошибки

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

  • Настройте виртуальную среду Python (используя virtualenv)

  • Установите соответствующие версии NumPy, сначала чтобы увидеть ошибку в действии, затем чтобы проверить её исправление

Issue 16354 используется в качестве примера.

Эта проблема была:

Заголовок: np.polymul возвращает тип np.float64 или np.complex128 при передаче аргумента, состоящего полностью из нулей

np.polymul возвращает объект с типом np.float64, когда один аргумент полностью нулевой, и оба аргумента имеют тип np.int64 или np.float32. Нечто подобное происходит с полностью нулевым np.complex64, дающим тип результата np.complex128.

Это не происходит с ненулевыми аргументами; там результат соответствует ожиданиям.

Эта ошибка отсутствует в np.convolve.

Пример воспроизводимого кода:

>>> import numpy as np
>>> np.__version__
'1.18.4'
>>> a = np.array([1,2,3])
>>> z = np.array([0,0,0])
>>> np.polymul(a.astype(np.int64), a.astype(np.int64)).dtype
dtype('int64')
>>> np.polymul(a.astype(np.int64), z.astype(np.int64)).dtype
dtype('float64')
>>> np.polymul(a.astype(np.float32), z.astype(np.float32)).dtype
dtype('float64')
>>> np.polymul(a.astype(np.complex64), z.astype(np.complex64)).dtype
dtype('complex128')
Numpy/Python version information:
>>> import sys, numpy; print(numpy.__version__, sys.version)
1.18.4 3.7.5 (default, Nov  7 2019, 10:50:52) [GCC 8.3.0]

1. Настройте виртуальную среду#

Создайте новый каталог, перейдите в него и настройте виртуальное окружение с помощью вашего предпочтительного метода. Например, вот как это сделать с использованием virtualenv на linux или macOS:

virtualenv venv_np_bug
source venv_np_bug/bin/activate

Это гарантирует, что системная/глобальная/установленная по умолчанию Python/NumPy не будет изменена.

2. Установите версию NumPy, в которой была сообщена ошибка#

В отчёте упоминается NumPy версии 1.18.4, поэтому это версия, которую вам нужно установить в этом случае.

Поскольку эта ошибка связана с выпуском, а не с конкретным коммитом, предварительно собранный wheel, установленный в вашем виртуальном окружении через pip будет достаточно:

pip install numpy==1.18.4

Некоторые ошибки могут потребовать сборки версии NumPy, указанной в отчёте о проблеме. Чтобы узнать, как это сделать, посетите Сборка из исходного кода.

3. Воспроизведите ошибку#

Проблема, о которой сообщалось в #16354 является тем неправильным dtype возвращается, если один из входных данных метода numpy.polymul является нулевым массивом.

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

>>> import numpy as np
>>> np.__version__
'...' # 1.18.4
>>> a = np.array([1,2,3])
>>> z = np.array([0,0,0])
>>> np.polymul(a.astype(np.int64), a.astype(np.int64)).dtype
dtype('int64')
>>> np.polymul(a.astype(np.int64), z.astype(np.int64)).dtype
dtype('...') # float64
>>> np.polymul(a.astype(np.float32), z.astype(np.float32)).dtype
dtype('...') # float64
>>> np.polymul(a.astype(np.complex64), z.astype(np.complex64)).dtype
dtype('...') # complex128

Как сообщалось, всякий раз, когда нулевой массив, z в примере выше, является одним из аргументов для numpy.polymul, некорректный dtype возвращается.

4. Проверить исправления в последней версии NumPy#

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

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

Для проверки исправления:

  1. Удалите версию NumPy, в которой ошибка все еще существует:

    pip uninstall numpy
    
  2. Установите последнюю версию NumPy:

    pip install numpy
    
  3. В вашем терминале Python запустите приведенный фрагмент кода, который вы использовали для проверки наличия ошибки, и подтвердите, что проблема устранена:

    >>> import numpy as np
    >>> np.__version__
    '...' # 1.18.4
    >>> a = np.array([1,2,3])
    >>> z = np.array([0,0,0])
    >>> np.polymul(a.astype(np.int64), a.astype(np.int64)).dtype
    dtype('int64')
    >>> np.polymul(a.astype(np.int64), z.astype(np.int64)).dtype
    dtype('int64')
    >>> np.polymul(a.astype(np.float32), z.astype(np.float32)).dtype
    dtype('float32')
    >>> np.polymul(a.astype(np.complex64), z.astype(np.complex64)).dtype
    dtype('complex64')
    

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

5. Поддержите разработку NumPy, проверяя и исправляя ошибки#

Перейти к Страница проблем NumPy на GitHub и проверьте, можете ли вы подтвердить существование других ошибок, которые ещё не подтверждены. В частности, разработчикам полезно знать, можно ли воспроизвести ошибку в более новой версии NumPy.

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