summaryrefslogtreecommitdiffstats
path: root/Objects/object.c
diff options
context:
space:
mode:
Diffstat (limited to 'Objects/object.c')
-rw-r--r--Objects/object.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/Objects/object.c b/Objects/object.c
index fd31e51..c56c3be 100644
--- a/Objects/object.c
+++ b/Objects/object.c
@@ -1417,6 +1417,43 @@ merge_class_dict(PyObject* dict, PyObject* aclass)
return 0;
}
+/* Helper for PyObject_Dir.
+ If obj has an attr named attrname that's a list, merge its string
+ elements into keys of dict.
+ Return 0 on success, -1 on error. Errors due to not finding the attr,
+ or the attr not being a list, are suppressed.
+*/
+
+static int
+merge_list_attr(PyObject* dict, PyObject* obj, char *attrname)
+{
+ PyObject *list;
+ int result = 0;
+
+ assert(PyDict_Check(dict));
+ assert(obj);
+ assert(attrname);
+
+ list = PyObject_GetAttrString(obj, attrname);
+ if (list == NULL)
+ PyErr_Clear();
+
+ else if (PyList_Check(list)) {
+ int i;
+ for (i = 0; i < PyList_GET_SIZE(list); ++i) {
+ PyObject *item = PyList_GET_ITEM(list, i);
+ if (PyString_Check(item)) {
+ result = PyDict_SetItem(dict, item, Py_None);
+ if (result < 0)
+ break;
+ }
+ }
+ }
+
+ Py_XDECREF(list);
+ return result;
+}
+
/* Like __builtin__.dir(arg). See bltinmodule.c's builtin_dir for the
docstring, which should be kept in synch with this implementation. */
@@ -1484,6 +1521,14 @@ PyObject_Dir(PyObject *arg)
if (masterdict == NULL)
goto error;
+ /* Merge in __members__ and __methods__ (if any).
+ XXX Would like this to go away someday; for now, it's
+ XXX needed to get at im_self etc of method objects. */
+ if (merge_list_attr(masterdict, arg, "__members__") < 0)
+ goto error;
+ if (merge_list_attr(masterdict, arg, "__methods__") < 0)
+ goto error;
+
/* Merge in attrs reachable from its class.
CAUTION: Not all objects have a __class__ attr. */
itsclass = PyObject_GetAttrString(arg, "__class__");