diff options
author | Tim Peters <tim.peters@gmail.com> | 2001-09-04 22:08:56 (GMT) |
---|---|---|
committer | Tim Peters <tim.peters@gmail.com> | 2001-09-04 22:08:56 (GMT) |
commit | 7eea37e8317bda88d9f50b862f13642e837957ce (patch) | |
tree | 33b41620f6b0e2266d19d43aa8fad9743f3bb3d4 /Python | |
parent | 2f760c35e2372dc50102305f407e5eed7e7b5c0a (diff) | |
download | cpython-7eea37e8317bda88d9f50b862f13642e837957ce.zip cpython-7eea37e8317bda88d9f50b862f13642e837957ce.tar.gz cpython-7eea37e8317bda88d9f50b862f13642e837957ce.tar.bz2 |
At Guido's suggestion, here's a new C API function, PyObject_Dir(), like
__builtin__.dir(). Moved the guts from bltinmodule.c to object.c.
Diffstat (limited to 'Python')
-rw-r--r-- | Python/bltinmodule.c | 138 |
1 files changed, 1 insertions, 137 deletions
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index d3d32c9..8fff44c 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -426,150 +426,14 @@ the effects of any future statements in effect in the code calling\n\ compile; if absent or zero these statements do influence the compilation,\n\ in addition to any features explicitly specified."; -/* Merge the __dict__ of aclass into dict, and recursively also all - the __dict__s of aclass's base classes. The order of merging isn't - defined, as it's expected that only the final set of dict keys is - interesting. - Return 0 on success, -1 on error. -*/ - -static int -merge_class_dict(PyObject* dict, PyObject* aclass) -{ - PyObject *classdict; - PyObject *bases; - - assert(PyDict_Check(dict)); - assert(aclass); - - /* Merge in the type's dict (if any). */ - classdict = PyObject_GetAttrString(aclass, "__dict__"); - if (classdict == NULL) - PyErr_Clear(); - else { - int status = PyDict_Update(dict, classdict); - Py_DECREF(classdict); - if (status < 0) - return -1; - } - - /* Recursively merge in the base types' (if any) dicts. */ - bases = PyObject_GetAttrString(aclass, "__bases__"); - if (bases != NULL) { - int i, n; - assert(PyTuple_Check(bases)); - n = PyTuple_GET_SIZE(bases); - for (i = 0; i < n; i++) { - PyObject *base = PyTuple_GET_ITEM(bases, i); - if (merge_class_dict(dict, base) < 0) { - Py_DECREF(bases); - return -1; - } - } - Py_DECREF(bases); - } - return 0; -} - static PyObject * builtin_dir(PyObject *self, PyObject *args) { PyObject *arg = NULL; - /* Set exactly one of these non-NULL before the end. */ - PyObject *result = NULL; /* result list */ - PyObject *masterdict = NULL; /* result is masterdict.keys() */ if (!PyArg_ParseTuple(args, "|O:dir", &arg)) return NULL; - - /* If no arg, return the locals. */ - if (arg == NULL) { - PyObject *locals = PyEval_GetLocals(); - if (locals == NULL) - goto error; - result = PyDict_Keys(locals); - if (result == NULL) - goto error; - } - - /* Elif this is some form of module, we only want its dict. */ - else if (PyObject_TypeCheck(arg, &PyModule_Type)) { - masterdict = PyObject_GetAttrString(arg, "__dict__"); - if (masterdict == NULL) - goto error; - assert(PyDict_Check(masterdict)); - } - - /* Elif some form of type or class, grab its dict and its bases. - We deliberately don't suck up its __class__, as methods belonging - to the metaclass would probably be more confusing than helpful. */ - else if (PyType_Check(arg) || PyClass_Check(arg)) { - masterdict = PyDict_New(); - if (masterdict == NULL) - goto error; - if (merge_class_dict(masterdict, arg) < 0) - goto error; - } - - /* Else look at its dict, and the attrs reachable from its class. */ - else { - PyObject *itsclass; - /* Create a dict to start with. CAUTION: Not everything - responding to __dict__ returns a dict! */ - masterdict = PyObject_GetAttrString(arg, "__dict__"); - if (masterdict == NULL) { - PyErr_Clear(); - masterdict = PyDict_New(); - } - else if (!PyDict_Check(masterdict)) { - Py_DECREF(masterdict); - masterdict = PyDict_New(); - } - else { - /* The object may have returned a reference to its - dict, so copy it to avoid mutating it. */ - PyObject *temp = PyDict_Copy(masterdict); - Py_DECREF(masterdict); - masterdict = temp; - } - if (masterdict == NULL) - goto error; - - /* Merge in attrs reachable from its class. - CAUTION: Not all objects have a __class__ attr. */ - itsclass = PyObject_GetAttrString(arg, "__class__"); - if (itsclass == NULL) - PyErr_Clear(); - else { - int status = merge_class_dict(masterdict, itsclass); - Py_DECREF(itsclass); - if (status < 0) - goto error; - } - } - - assert((result == NULL) ^ (masterdict == NULL)); - if (masterdict != NULL) { - /* The result comes from its keys. */ - assert(result == NULL); - result = PyDict_Keys(masterdict); - if (result == NULL) - goto error; - } - - assert(result); - if (PyList_Sort(result) != 0) - goto error; - else - goto normal_return; - - error: - Py_XDECREF(result); - result = NULL; - /* fall through */ - normal_return: - Py_XDECREF(masterdict); - return result; + return PyObject_Dir(arg); } static char dir_doc[] = |