Issues with getattr in a C extension

Hi,

I’m new to writing extensions and things were going well until I needed a custom getattr on a class. Each Python object wraps a large chunk of C++ code that does a Monte-Carlo simulation, so I will need a getattr that can “reach through” into the underlying objects for the output values. This has been going well with simple types, but anything that I’ve simply stored in the class as a Python object (typically strings) keeps getting corrupted. I’ve looked over the documentation on extension modules and I can’t find a simple example of custom getattr function.

Here’s a snippet of the code. I’m wondering if I need to do something around reference counting?

static PyObject *
MarketSegmentObject_getattr(MarketSegmentObject *obj, char *attr_name)
{
    if (strcmp(attr_name, "segment") == 0) {
        // This is a PyObject* with a string in it that's setup in the init
        // This seems to be causing me trouble
        return obj->segment;  
    }
    else if (strcmp(attr_name, "base_demand") == 0) {
        // This seems to work fine
        return PyFloat_FromDouble(obj->baseDemand);
    }
}

Regards,
Alan

You must return a new reference, so you have to incref obj->segment before returning.

Also, you could use this approach, letting the C API do the work for you:

// Assuming you are using heap types, add a members struct
static struct PyMemberDef members[] = {
    {"segment", T_LONG, offsetof(MarketSegmentObject, segment), READONLY},
    {"base_demand", T_LONG, offsetof(MarketSegmentObject, baseDemand), READONLY},
    {NULL},
};

// Assuming you already have a slots array; add the methods member from above:
static PyTypeSlot slots[] = {
    {Py_tp_methods, methods},  // <= add this slot
    {0, NULL},
};
1 Like

https://docs.python.org/3/c-api/structures.html#c.PyMemberDef

Erlend,

Thanks for your note. Just after posting this query I left to go on an errand, got barely a mile down the road and figured out what I’d done wrong. Just now put in the increment and everything works great :slight_smile:

Some of the variables I’m storing are Python strings and complex objects. I’ll read up on the slots too. The classes I’ve built already have a bunch of methods.

BTW, wrapping up big chunks of C/C++ is Python is really cool once you get your head around making it work!

Regards,
Alan

1 Like