3

I'm trying to write a C++ extension for Python (3.x) that allows me to use a specific hardware shield for the Raspberry Pi.
I haven't got any experience in writing C and/or C++, but using the documentation on the Python website, I actually got things working. What I would like to do is make my type a Singleton, but if the init-method returns with an error (-1), the second call to the constructor will mess things up. If the init returns without errors, it actually works as expected.

The important parts of my code:

static PyObject *
MyType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    static MyType *self = NULL;  /* static to create a Singleton */

    if (self == NULL) {
        self = (MyType *)type->tp_alloc(type, 0);

        self->is_initialized = false;
    }
    else {
        Py_XINCREF(self);
    }

    return (PyObject *)self;
}

static int
MyType_init(MyType *self, PyObject *args, PyObject *kwds)
{
    const char *i2c_addr;

    self->rpi_model = RPI_MODEL_B;
    self->enabled_components = COMPONENTS_ALL_BIT;

    static char *kwlist[] = {"rpi_model", "enabled_components", NULL};

    if (self != NULL && !self->is_initialized) {
        if (!PyArg_ParseTupleAndKeywords(args, kwds, "|ii", kwlist, &self->rpi_model, &self->enabled_components)) {

            return -1;
        }
    }

    /*
        DO SOME INITIALIZATION STUFF
    */

    if (!self->component_A->testConnection()) {
        PyErr_SetString(InitializationException, "Unable to communicate with component_A.");
        return -1;
    }

    self->is_initialized = true;
    return 0;
}

I also installed the following funtion in the tp_dealloc member:

static void
MyType_dealloc(PyObject *self)
{
    Py_TYPE(self)->tp_free((PyObject*)self);
}

I put some print-statements in these methods (for debugging) and it seems that in the second call to MyType_new, self != NULL, although the MyType_dealloc method has been executed upon failure of the initialization.

Is anybody able to point me in the right direction?

bennierex
  • 31
  • 1

1 Answers1

0

It looks like your MyType_dealloc isn't setting self back to NULL.

Also, there is no need for you to have both __new__ and __init__ -- just put it all in __new__.

Ethan Furman
  • 63,992
  • 20
  • 159
  • 237