Почему функция PyLong_AsUnsignedLongLong не может преобразовать элемент numpy.uint64, тогда как PyLong_AsLongLong успешно выполняется? - PullRequest
0 голосов
/ 11 ноября 2019

Я работаю над C-расширением для Python, которое реализует метод, который преобразует список numpy элементов (в данном случае numpy.uint64) в unsigned long long C-тип (с использованием функции PyLong_AsUnsignedLongLong). Затем элементы списка суммируются, и полученная сумма возвращается на слой Python.

Чтобы создать модуль, я написал этот код в testmodule.c:

#include <Python.h>

static PyObject *method_sum_list_u64(PyObject *self, PyObject *args);

static PyMethodDef testmoduleMethods[] = {
    {"sum_list_u64", method_sum_list_u64, METH_VARARGS, "docs"},
    {NULL, NULL, 0, NULL}
};

static struct PyModuleDef testmodule = {
    PyModuleDef_HEAD_INIT,
    "testmodule",
    "docs",
    -1,
    testmoduleMethods
};

PyMODINIT_FUNC PyInit_testmodule(void) {
    return PyModule_Create(&testmodule);
}

И здесьмой метод:

static PyObject *method_print_list_u64(PyObject *self, PyObject *args) {
    uint64_t sum = 0;
    PyObject *input_list;

    if (!PyArg_ParseTuple(args, "O!", &PyList_Type, &input_list))
    {
        return NULL;
    }

    Py_ssize_t data_points = PyList_Size(input_list);

    for (Py_ssize_t i = 0; i < data_points; i++)
    {
        PyObject *item = PyList_GetItem(input_list, i);
        sum += PyLong_AsUnsignedLongLong(item);
    }

    return PyLong_FromUnsignedLongLong(sum);
}

Мой setup.py файл:

from setuptools import setup, Extension

def main():
    setup(name="testmodule",
          version="1.0.1",
          description="Python interface for the testmodule C library function",
          ext_modules=[Extension("testmodule", ["testmodule.c"])])

if __name__ == "__main__":
    main()

И простой тестовый скрипт с именем mytest.py:

import numpy as np
import testmodule

input_list = [np.uint64(1000)]
print(testmodule.sum_list_u64(input_list))

Для воспроизведенияя запускаю ошибку:

$ python setup.py install
$ python mytest.py
TypeError: an integer is required

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "mytest.py", line 5, in <module>
    print(testmodule.sum_list_u64(input_list))
SystemError: <built-in function sum_list_u64> returned a result with an error set

Теперь, если я заменю PyLong_AsUnsignedLongLong на PyLong_AsLongLong, все работает нормально. Почему PyLong_AsUnsignedLongLong терпит неудачу, а PyLong_AsLongLong нет?

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