diff options
author | Benjamin Peterson <benjamin@python.org> | 2011-06-11 21:12:08 (GMT) |
---|---|---|
committer | Benjamin Peterson <benjamin@python.org> | 2011-06-11 21:12:08 (GMT) |
commit | 3bbb72265411585e64a5d2ccb5ba51763f20e311 (patch) | |
tree | 8ec38156f5e1b1851dcc8f0490e941bb56435427 /Objects | |
parent | 703f7c4bf5fa98f9b8b11593d3fa37eb68eae896 (diff) | |
download | cpython-3bbb72265411585e64a5d2ccb5ba51763f20e311.zip cpython-3bbb72265411585e64a5d2ccb5ba51763f20e311.tar.gz cpython-3bbb72265411585e64a5d2ccb5ba51763f20e311.tar.bz2 |
allow __dir__ to return any sequence
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/object.c | 45 |
1 files changed, 15 insertions, 30 deletions
diff --git a/Objects/object.c b/Objects/object.c index e42c1d9..80ffddb 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -1205,6 +1205,10 @@ _dir_locals(void) Py_DECREF(names); return NULL; } + if (PyList_Sort(names)) { + Py_DECREF(names); + return NULL; + } /* the locals don't need to be DECREF'd */ return names; } @@ -1213,7 +1217,7 @@ _dir_locals(void) static PyObject * _dir_object(PyObject *obj) { - PyObject *result; + PyObject *result, *sorted; static PyObject *dir_str = NULL; PyObject *dirfunc = _PyObject_LookupSpecial(obj, "__dir__", &dir_str); @@ -1228,18 +1232,16 @@ _dir_object(PyObject *obj) Py_DECREF(dirfunc); if (result == NULL) return NULL; - - /* result must be a list */ - /* XXX(gbrandl): could also check if all items are strings */ - if (!PyList_Check(result)) { - PyErr_Format(PyExc_TypeError, - "__dir__() must return a list, not %.200s", - Py_TYPE(result)->tp_name); - Py_DECREF(result); - result = NULL; + /* return sorted(result) */ + sorted = PySequence_List(result); + Py_DECREF(result); + if (sorted == NULL) + return NULL; + if (PyList_Sort(sorted)) { + Py_DECREF(sorted); + return NULL; } - - return result; + return sorted; } /* Implementation of dir() -- if obj is NULL, returns the names in the current @@ -1249,24 +1251,7 @@ _dir_object(PyObject *obj) PyObject * PyObject_Dir(PyObject *obj) { - PyObject * result; - - if (obj == NULL) - /* no object -- introspect the locals */ - result = _dir_locals(); - else - /* object -- introspect the object */ - result = _dir_object(obj); - - assert(result == NULL || PyList_Check(result)); - - if (result != NULL && PyList_Sort(result) != 0) { - /* sorting the list failed */ - Py_DECREF(result); - result = NULL; - } - - return result; + return (obj == NULL) ? _dir_locals() : _dir_object(obj); } /* |