[pypy-svn] pypy default: issue686 (nekto0n) Fix dir() on objects with a broken __getattribute__

amauryfa commits-noreply at bitbucket.org
Mon Apr 18 10:16:06 CEST 2011


Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch: 
Changeset: r43440:addc4bcf08a3
Date: 2011-04-18 09:53 +0200
http://bitbucket.org/pypy/pypy/changeset/addc4bcf08a3/

Log:	issue686 (nekto0n) Fix dir() on objects with a broken
	__getattribute__

diff --git a/pypy/module/__builtin__/test/test_builtin.py b/pypy/module/__builtin__/test/test_builtin.py
--- a/pypy/module/__builtin__/test/test_builtin.py
+++ b/pypy/module/__builtin__/test/test_builtin.py
@@ -110,6 +110,13 @@
             __dict__ = 8
         raises(TypeError, dir, Foo("foo"))
 
+    def test_dir_broken_object(self):
+        class Foo(object):
+            x = 3
+            def __getattribute__(self, name):
+                return name
+        assert dir(Foo()) == []
+
     def test_dir_custom(self):
         class Foo(object):
             def __dir__(self):

diff --git a/pypy/module/__builtin__/app_inspect.py b/pypy/module/__builtin__/app_inspect.py
--- a/pypy/module/__builtin__/app_inspect.py
+++ b/pypy/module/__builtin__/app_inspect.py
@@ -76,8 +76,8 @@
         result.sort()
         return result
 
-    elif hasattr(obj, '__dir__'):
-        result = obj.__dir__()
+    elif hasattr(type(obj), '__dir__'):
+        result = type(obj).__dir__(obj)
         if not isinstance(result, list):
             raise TypeError("__dir__() must return a list, not %r" % (
                 type(result),))
@@ -87,11 +87,14 @@
     else: #(regular item)
         Dict = {}
         try:
-            Dict.update(obj.__dict__)
-        except AttributeError: pass
+            if isinstance(obj.__dict__, dict):
+                Dict.update(obj.__dict__)
+        except AttributeError:
+            pass
         try:
             Dict.update(_classdir(obj.__class__))
-        except AttributeError: pass
+        except AttributeError:
+            pass
 
         ## Comment from object.c:
         ## /* Merge in __members__ and __methods__ (if any).
@@ -99,10 +102,14 @@
         ## XXX needed to get at im_self etc of method objects. */
         for attr in ['__members__','__methods__']:
             try:
-                for item in getattr(obj, attr):
+                l = getattr(obj, attr)
+                if not isinstance(l, list):
+                    continue
+                for item in l:
                     if isinstance(item, types.StringTypes):
                         Dict[item] = None
-            except (AttributeError, TypeError): pass
+            except (AttributeError, TypeError):
+                pass
 
         result = Dict.keys()
         result.sort()


More information about the Pypy-commit mailing list