Python C api Исключительный класс внутри класса - PullRequest
0 голосов
/ 17 марта 2019

Я пытаюсь выдать исключение, которое определено внутри класса в модуле расширения, созданном с помощью Python C API.

Вот что я хочу в Python C API, но написано на Python:

class Graph:
    class TooManyVerticesError( Exception ): pass

    def addVertex( self ):
        if self.__order == 16:
            raise Graph.TooManyVerticesError( "too many vertices" )
        for v in range( self.__order ):
            self.__matrix[v] += [False]
        self.__order += 1
        self.__matrix += [ [False] * self.__order ]

Вот что я сейчас написал с python C api:

#define ERROR return NULL;

PyObject *TooManyVerticesError;

typedef struct {
    PyObject_HEAD
    size_t __order;  /* the maximum number of elements in q_elements */
    std::vector<std::vector<int>> AdjacencyList;  
} ListaSasiedztwa;

static
PyObject* addVertex(ListaSasiedztwa* self, PyObject* args)
{
    int u, v;
    // Process arguments
    PyArg_ParseTuple(args, "ii",
    &u,
    &v);

    if (self->__order == 16)
    {
        PyErr_SetString(TooManyVerticesError, "too many vertices");
        ERROR
    }
    std::vector<int> vertexList;
    self->AdjacencyList.push_back(vertexList);
    return NULL;
}

PyMODINIT_FUNC PyInit_simple_graphs(void)
{
    if (PyType_Ready(&ListaSasiedztwaType) < 0) return NULL;
    PyObject* m = PyModule_Create(&cSimpleGraphsModule);
    if (m == NULL) return NULL;


    TooManyVerticesError = PyErr_NewException("simple_graphs.TooManyVerticesError", NULL, NULL);
    PyDict_SetItemString(ListaSasiedztwaType.tp_dict, "TooManyVerticesError", TooManyVerticesError);


    Py_INCREF(&ListaSasiedztwaType);
    PyModule_AddObject(m, "ListaSasiedztwa",
        (PyObject *)&ListaSasiedztwaType);

    return m;
}

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

класс 'simple_graphs.ListaSasiedztwa' вернул результат с установленной ошибкой.

Должен ли я как-то добавить это Исключение в качестве члена структуры? Я не знаю, относится ли ListaSasiedztwaType к этой проблеме, поэтому я еще не добавил ее.

Ответы [ 2 ]

1 голос
/ 17 марта 2019

Я думаю, что вы на самом деле нажимаете return NULL; в конце функции, которую вы достигаете в случае «без ошибок». Это NULL указывает Python, что они должны быть набором исключений, но так как их нет, вы получаете общее SystemError от Python.

Я подозреваю, что вы пытаетесь вернуть объект Python None - используйте вместо этого макрос Py_RETURN_NONE.

0 голосов
/ 18 марта 2019

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

...