summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorTim Peters <tim.peters@gmail.com>2001-09-04 22:08:56 (GMT)
committerTim Peters <tim.peters@gmail.com>2001-09-04 22:08:56 (GMT)
commit7eea37e8317bda88d9f50b862f13642e837957ce (patch)
tree33b41620f6b0e2266d19d43aa8fad9743f3bb3d4 /Python
parent2f760c35e2372dc50102305f407e5eed7e7b5c0a (diff)
downloadcpython-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.c138
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[] =