From: <pj...@us...> - 2008-12-10 00:07:25
|
Revision: 5726 http://jython.svn.sourceforge.net/jython/?rev=5726&view=rev Author: pjenvey Date: 2008-12-10 00:07:22 +0000 (Wed, 10 Dec 2008) Log Message: ----------- match CPython's dir() more closely fixes #1196 pointed out by doublep Modified Paths: -------------- trunk/jython/Lib/test/test_builtin_jy.py trunk/jython/src/org/python/core/PyClass.java trunk/jython/src/org/python/core/PyObject.java trunk/jython/src/org/python/core/PyType.java Modified: trunk/jython/Lib/test/test_builtin_jy.py =================================================================== --- trunk/jython/Lib/test/test_builtin_jy.py 2008-12-09 22:25:56 UTC (rev 5725) +++ trunk/jython/Lib/test/test_builtin_jy.py 2008-12-10 00:07:22 UTC (rev 5726) @@ -16,6 +16,13 @@ raise TypeError() self.assert_(not hasattr(Foo(), 'bar')) + def test_dir(self): + # for http://bugs.jython.org/issue1063 + class Foo(object): + def __getattribute__(self, name): + return name + self.assertEqual(dir(Foo()), []) + class LoopTest(unittest.TestCase): def test_break(self): Modified: trunk/jython/src/org/python/core/PyClass.java =================================================================== --- trunk/jython/src/org/python/core/PyClass.java 2008-12-09 22:25:56 UTC (rev 5725) +++ trunk/jython/src/org/python/core/PyClass.java 2008-12-10 00:07:22 UTC (rev 5726) @@ -281,11 +281,7 @@ } public void __rawdir__(PyDictionary accum) { - addKeys(accum, "__dict__"); - PyObject[] bases = __bases__.getArray(); - for (PyObject base : bases) { - base.__rawdir__(accum); - } + mergeClassDict(accum, this); } /** Modified: trunk/jython/src/org/python/core/PyObject.java =================================================================== --- trunk/jython/src/org/python/core/PyObject.java 2008-12-09 22:25:56 UTC (rev 5725) +++ trunk/jython/src/org/python/core/PyObject.java 2008-12-10 00:07:22 UTC (rev 5726) @@ -903,24 +903,54 @@ return __findattr__(name); } - protected void addKeys(PyDictionary accum, String attr) { + protected void mergeListAttr(PyDictionary accum, String attr) { PyObject obj = __findattr__(attr); - if (obj == null) + if (obj == null) { return; + } if (obj instanceof PyList) { for (PyObject name : obj.asIterable()) { accum.__setitem__(name, Py.None); } - } else { + } + } + + protected void mergeDictAttr(PyDictionary accum, String attr) { + PyObject obj = __findattr__(attr); + if (obj == null) { + return; + } + if (obj instanceof PyDictionary || obj instanceof PyStringMap + || obj instanceof PyDictProxy) { accum.update(obj); } } + protected void mergeClassDict(PyDictionary accum, PyObject aClass) { + // Merge in the type's dict (if any) + aClass.mergeDictAttr(accum, "__dict__"); + + // Recursively merge in the base types' (if any) dicts + PyObject bases = aClass.__findattr__("__bases__"); + if (bases == null) { + return; + } + // We have no guarantee that bases is a real tuple + int len = bases.__len__(); + for (int i = 0; i < len; i++) { + mergeClassDict(accum, bases.__getitem__(i)); + } + } + protected void __rawdir__(PyDictionary accum) { - addKeys(accum, "__dict__"); - addKeys(accum, "__methods__"); - addKeys(accum, "__members__"); - fastGetClass().__rawdir__(accum); + mergeDictAttr(accum, "__dict__"); + mergeListAttr(accum, "__methods__"); + mergeListAttr(accum, "__members__"); + // Class dict is a slower, more manual merge to match CPython + PyObject itsClass = __findattr__("__class__"); + if (itsClass != null) { + mergeClassDict(accum, itsClass); + } } /** Modified: trunk/jython/src/org/python/core/PyType.java =================================================================== --- trunk/jython/src/org/python/core/PyType.java 2008-12-09 22:25:56 UTC (rev 5725) +++ trunk/jython/src/org/python/core/PyType.java 2008-12-10 00:07:22 UTC (rev 5726) @@ -1129,13 +1129,7 @@ } protected void __rawdir__(PyDictionary accum) { - PyObject[] mro = this.mro; - if (mro == null) { - return; - } - for (PyObject element : mro) { - element.addKeys(accum, "__dict__"); - } + mergeClassDict(accum, this); } public String fastGetName() { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |