Skip to content

Commit

Permalink
Lookup attr in class if obj doesn't have it
Browse files Browse the repository at this point in the history
  • Loading branch information
sudo-panda authored and vgvassilev committed Jul 15, 2023
1 parent 0074db0 commit bc0b093
Showing 1 changed file with 27 additions and 1 deletion.
28 changes: 27 additions & 1 deletion src/CPPInstance.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -838,6 +838,32 @@ static PyObject* op_str(CPPInstance* self)
return op_repr(self);
}

//----------------------------------------------------------------------------
static PyObject* op_getattro(PyObject* pyobj, PyObject* pyname)
{
// Check if we can access the attribute at the object level
PyObject* attr = PyObject_GenericGetAttr(pyobj, pyname);
if (attr)
return attr;

// If it's not AttributeError the attribute was found and something else failed
if (!PyErr_ExceptionMatches(PyExc_AttributeError))
return nullptr;

// Keep the error aside to be used in case lookup on class level fails
PyObject* pytype = 0, *pyvalue = 0, *pytrace = 0;
PyErr_Fetch(&pytype, &pyvalue, &pytrace);

// Perform a class level lookup for statics, enums etc.
CPPClass* klass = (CPPClass*)Py_TYPE(pyobj);
attr = PyObject_GetAttr((PyObject*)klass, pyname);
if (attr)
return attr;

PyErr_Restore(pytype, pyvalue, pytrace);
return nullptr;
}

//-----------------------------------------------------------------------------
static PyObject* op_getownership(CPPInstance* pyobj, void*)
{
Expand Down Expand Up @@ -1030,7 +1056,7 @@ PyTypeObject CPPInstance_Type = {
(hashfunc)op_hash, // tp_hash
0, // tp_call
(reprfunc)op_str, // tp_str
0, // tp_getattro
(getattrofunc)op_getattro, // tp_getattro
0, // tp_setattro
0, // tp_as_buffer
Py_TPFLAGS_DEFAULT |
Expand Down

0 comments on commit bc0b093

Please sign in to comment.