0

I'm trying to throw exception which is defined inside class in extension module created with python C api.

Here is what I want in python C api, but written in 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 ]

Here is what I have now written with 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;
}

Everything builds correctly, I can create object of type ListaSasiedztwa. But when exception should be thrown I have Exception of type SystemError with message:

class 'simple_graphs.ListaSasiedztwa' returned a result with an error set.

Should I add this Exception as structure member somehow? I don't know if ListaSasiedztwaType is relevant in this problem so I didn't add it yet.

2 Answers2

1

I think you're actually hitting the return NULL; at the end of the function which you reach in the "non-error" case. This NULL indicates to Python that their should be an exception set, but since there isn't one you get the general SystemError from Python..

I suspect you're trying to return the Python None object - use the macro Py_RETURN_NONE instead.

DavidW
  • 29,336
  • 6
  • 55
  • 86
0

It occured that addVertex was called from another method which didn't pass return value which had to be NULL.