C extension - new and init functions

Paul Moore p.f.moore at gmail.com
Sun Nov 16 22:34:55 CET 2008


I have a C extension type, "Pattern", where my type manages a
dynamically allocated memory block (of "instructions", the details
aren't important).

The basic constructor builds a pattern with a single instruction
("End") as follows:

static PyObject *
Pattern_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    Pattern *self;

    self = (Pattern *)type->tp_alloc(type, 0);
    self->prog = NULL;
    return (PyObject *)self;
}

static int
Pattern_init(Pattern *self, PyObject *args, PyObject *kwds)
{
    self->prog = newpatt(0);
    if (self->prog == NULL)
	return -1;

    return 0;
}

This is fine, but in a lot of cases I want to allocate a Pattern with
a larger buffer (which will be filled in C before being passed back to
Python code). I want to allow the type to be subclassed, so I believe
that any allocation I do in C should be by calling the type
constructor - so my code to build instances should have the form (for
a Pattern classmethod):

static PyObject *
Pattern_XXX(PyObject *cls, PyObject *arg)
{
    ...

    result = PyObject_CallFunction(cls, "");
    if (result == NULL)
	return NULL;

    ...
}

OK, but that allocates the initial buffer, which I will then throw
away. In practice, this isn't a significant issue (the overhead of one
allocation and one deallocation isn't going to wreck things!) but it
feels somehow clumsy. However, I can't see an obvious way to refactor
the code so that building the object and assigning the buffer are
separate - so that I can write a function like Pattern_init, which
allocates a differently sized buffer (well, I could, but if I did, I'd
have no way of using it that respects subclassing...

Can anybody offer me any suggestions on how to code this (or
confirmation that there's no way, and I should just live with the
unwanted allocation)?

Thanks,
Paul.



More information about the Python-list mailing list