summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>1997-05-06 16:36:57 (GMT)
committerGuido van Rossum <guido@python.org>1997-05-06 16:36:57 (GMT)
commit666b17a28091be3ab1fdd935b881113416787622 (patch)
treeba3f0434b77768c0376a0da85f679881b18face2 /Python
parent0f00c5e2dcd6f1518253380bd433ef95ec0ac8a4 (diff)
downloadcpython-666b17a28091be3ab1fdd935b881113416787622.zip
cpython-666b17a28091be3ab1fdd935b881113416787622.tar.gz
cpython-666b17a28091be3ab1fdd935b881113416787622.tar.bz2
New dir() function --
- uses abstract interface where possible - uses __members__ and __methods__ - returns [] when an object has no info available
Diffstat (limited to 'Python')
-rw-r--r--Python/bltinmodule.c70
1 files changed, 48 insertions, 22 deletions
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c
index fd8dc80..2461904 100644
--- a/Python/bltinmodule.c
+++ b/Python/bltinmodule.c
@@ -384,39 +384,65 @@ builtin_dir(self, args)
PyObject *self;
PyObject *args;
{
- PyObject *v = NULL;
- PyObject *d;
+ static char *attrlist[] = {"__members__", "__methods__", NULL};
+ PyObject *v = NULL, *l = NULL, *m = NULL;
+ PyObject *d, *x;
+ int i;
+ char **s;
if (!PyArg_ParseTuple(args, "|O:dir", &v))
return NULL;
if (v == NULL) {
- d = PyEval_GetLocals();
- Py_INCREF(d);
+ x = PyEval_GetLocals();
+ if (x == NULL)
+ goto error;
+ l = PyMapping_Keys(x);
+ if (l == NULL)
+ goto error;
}
else {
d = PyObject_GetAttrString(v, "__dict__");
- if (d == NULL) {
- PyErr_SetString(PyExc_TypeError,
- "dir() argument must have __dict__ attribute");
- return NULL;
+ if (d == NULL)
+ PyErr_Clear();
+ else {
+ l = PyMapping_Keys(d);
+ if (l == NULL)
+ PyErr_Clear();
+ Py_DECREF(d);
}
- }
- if (PyDict_Check(d)) {
- v = PyDict_Keys(d);
- if (PyList_Sort(v) != 0) {
- Py_DECREF(v);
- v = NULL;
+ if (l == NULL) {
+ l = PyList_New(0);
+ if (l == NULL)
+ goto error;
}
- }
- else {
- v = PyObject_CallMethod(d, "keys", NULL);
- if (v == NULL) {
- PyErr_Clear();
- v = PyList_New(0);
+ for (s = attrlist; *s != NULL; s++) {
+ m = PyObject_GetAttrString(v, *s);
+ if (m == NULL) {
+ PyErr_Clear();
+ continue;
+ }
+ for (i = 0; ; i++) {
+ x = PySequence_GetItem(m, i);
+ if (x == NULL) {
+ PyErr_Clear();
+ break;
+ }
+ if (PyList_Append(l, x) != 0) {
+ Py_DECREF(x);
+ Py_DECREF(m);
+ goto error;
+ }
+ Py_DECREF(x);
+ }
+ Py_DECREF(m);
}
}
- Py_DECREF(d);
- return v;
+ if (PyList_Sort(l) != 0)
+ goto error;
+ return l;
+ error:
+ Py_XDECREF(l);
+ return NULL;
}
static PyObject *