Index: Include/moduleobject.h =================================================================== --- Include/moduleobject.h (revision 79823) +++ Include/moduleobject.h (working copy) @@ -17,6 +17,7 @@ PyAPI_FUNC(char *) PyModule_GetName(PyObject *); PyAPI_FUNC(char *) PyModule_GetFilename(PyObject *); PyAPI_FUNC(void) _PyModule_Clear(PyObject *); +PyAPI_FUNC(PyObject *) PyModule_GetAttr(PyObject *, PyObject *); #ifdef __cplusplus } Index: Include/object.h =================================================================== --- Include/object.h (revision 79823) +++ Include/object.h (working copy) @@ -478,6 +478,7 @@ PyAPI_FUNC(PyObject *) PyObject_SelfIter(PyObject *); PyAPI_FUNC(PyObject *) _PyObject_NextNotImplemented(PyObject *); PyAPI_FUNC(PyObject *) PyObject_GenericGetAttr(PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) PyObject_GenericFindAttr(PyObject *, PyObject *); PyAPI_FUNC(int) PyObject_GenericSetAttr(PyObject *, PyObject *, PyObject *); PyAPI_FUNC(long) PyObject_Hash(PyObject *); Index: Objects/object.c =================================================================== --- Objects/object.c (revision 79823) +++ Objects/object.c (working copy) @@ -1320,6 +1320,19 @@ PyObject_GenericGetAttr(PyObject *obj, PyObject *name) { PyTypeObject *tp = Py_TYPE(obj); + PyObject *res = PyObject_GenericFindAttr(obj, name); + if(res == NULL) { + PyErr_Format(PyExc_AttributeError, + "'%.50s' object has no attribute '%.400s'", + tp->tp_name, PyString_AS_STRING(name)); + } + return res; +} + +PyObject * +PyObject_GenericFindAttr(PyObject *obj, PyObject *name) +{ + PyTypeObject *tp = Py_TYPE(obj); PyObject *descr = NULL; PyObject *res = NULL; descrgetfunc f; @@ -1439,9 +1452,9 @@ goto done; } - PyErr_Format(PyExc_AttributeError, - "'%.50s' object has no attribute '%.400s'", - tp->tp_name, PyString_AS_STRING(name)); + /* Indicate that the attribute is not found, and the caller should + raise AttributeError */ + res = NULL; done: Py_DECREF(name); return res; Index: Objects/moduleobject.c =================================================================== --- Objects/moduleobject.c (revision 79823) +++ Objects/moduleobject.c (working copy) @@ -146,6 +146,21 @@ } +PyObject * +PyModule_GetAttr(PyObject *mod, PyObject *name) +{ + char *mod_name; + PyObject *res = PyObject_GenericFindAttr(mod, name); + if(res == NULL) { + mod_name = PyModule_GetName(mod); + PyErr_Format(PyExc_AttributeError, + "module object '%.50s' has no attribute '%.400s'", + mod_name, PyString_AS_STRING(name)); + } + return res; +} + + /* Methods */ static int @@ -236,7 +251,7 @@ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ + PyModule_GetAttr, /* tp_getattro */ PyObject_GenericSetAttr, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |