Author: Philip Jenvey <[email protected]>
Branch: py3.3
Changeset: r72648:49884de0d7c3
Date: 2014-08-01 15:39 -0700
http://bitbucket.org/pypy/pypy/changeset/49884de0d7c3/

Log:    Merged in numerodix/pypy/py3.3 (pull request #255)

        factor dir() built-in out into object, type and module methods

diff --git a/pypy/interpreter/module.py b/pypy/interpreter/module.py
--- a/pypy/interpreter/module.py
+++ b/pypy/interpreter/module.py
@@ -123,3 +123,14 @@
         except OperationError:
             __file__ = u'?'
         return space.wrap(u"<module %s from %s>" % (name, __file__))
+
+    def descr_module__dir__(self, space):
+        try:
+            w__dict__ = space.getattr(self, space.wrap('__dict__'))
+            result = space.listview(w__dict__)
+            w_result = space.wrap(result)
+            return w_result
+        except OperationError as e:
+            if e.match(space, space.w_AttributeError):
+                return space.wrap([])
+            raise
diff --git a/pypy/interpreter/test/test_module.py 
b/pypy/interpreter/test/test_module.py
--- a/pypy/interpreter/test/test_module.py
+++ b/pypy/interpreter/test/test_module.py
@@ -68,6 +68,11 @@
         m = type(_pypy_interact).__new__(type(_pypy_interact))
         assert repr(m).startswith("<module '?'")
 
+    def test_dir(self):
+        import sys
+        items = sys.__dir__()
+        assert sorted(items) == dir(sys)
+
     def test_package(self):
         import sys
         import os
diff --git a/pypy/interpreter/typedef.py b/pypy/interpreter/typedef.py
--- a/pypy/interpreter/typedef.py
+++ b/pypy/interpreter/typedef.py
@@ -779,6 +779,7 @@
     __new__ = interp2app(Module.descr_module__new__.im_func),
     __init__ = interp2app(Module.descr_module__init__),
     __repr__ = interp2app(Module.descr_module__repr__),
+    __dir__ = interp2app(Module.descr_module__dir__),
     __reduce__ = interp2app(Module.descr__reduce__),
     __dict__ = GetSetProperty(descr_get_dict, cls=Module), # module 
dictionaries are readonly attributes
     __doc__ = 'module(name[, doc])\n\nCreate a module object.\nThe name must 
be a string; the optional doc argument can have any type.'
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
@@ -45,8 +45,6 @@
         local_names.sort()
         return local_names
 
-    import types
-
     obj = args[0]
 
     dir_meth = lookup_special(obj, "__dir__")
@@ -56,58 +54,5 @@
             result = list(result)  # Will throw TypeError if not iterable
         result.sort()
         return result
-    elif isinstance(obj, types.ModuleType):
-        try:
-            result = list(obj.__dict__)
-            result.sort()
-            return result
-        except AttributeError:
-            return []
 
-    elif isinstance(obj, type):
-        #Don't look at __class__, as metaclass methods would be confusing.
-        result = list(_classdir(obj).keys())
-        result.sort()
-        return result
-
-    else: #(regular item)
-        Dict = {}
-        try:
-            if isinstance(obj.__dict__, dict):
-                Dict.update(obj.__dict__)
-        except AttributeError:
-            pass
-        try:
-            Dict.update(_classdir(obj.__class__))
-        except AttributeError:
-            pass
-        result = list(Dict.keys())
-        result.sort()
-        return result
-
-def _classdir(klass):
-    """Return a dict of the accessible attributes of class/type klass.
-
-    This includes all attributes of klass and all of the
-    base classes recursively.
-
-    The values of this dict have no meaning - only the keys have
-    meaning.  
-    """
-    Dict = {}
-    try:
-        Dict.update(klass.__dict__)
-    except AttributeError: pass 
-    try:
-        # XXX - Use of .__mro__ would be suggested, if the existance
-        #   of that attribute could be guarranted.
-        bases = klass.__bases__
-    except AttributeError: pass
-    else:
-        try:
-            #Note that since we are only interested in the keys,
-            #  the order we merge classes is unimportant
-            for base in bases:
-                Dict.update(_classdir(base))
-        except TypeError: pass
-    return Dict
+    return []  # we should never reach here since object.__dir__ exists
diff --git a/pypy/objspace/std/objecttype.py b/pypy/objspace/std/objecttype.py
--- a/pypy/objspace/std/objecttype.py
+++ b/pypy/objspace/std/objecttype.py
@@ -19,6 +19,40 @@
                 classname = u'%s.%s' % (modulename, classname)
     return w_obj.getrepr(space, u'%s object' % (classname,))
 
+def descr__dir__(space, w_obj):
+    w_result = space.appexec([w_obj], """(obj):
+        def _classdir(klass):
+            Dict = {}
+            try:
+                Dict.update(klass.__dict__)
+            except AttributeError: pass
+            try:
+                bases = klass.__mro__
+            except AttributeError: pass
+            else:
+                try:
+                    #Note that since we are only interested in the keys,
+                    #  the order we merge classes is unimportant
+                    for base in bases:
+                        Dict.update(base.__dict__)
+                except TypeError: pass
+            return Dict
+
+        Dict = {}
+        try:
+            if isinstance(obj.__dict__, dict):
+                Dict.update(obj.__dict__)
+        except AttributeError:
+            pass
+        try:
+            Dict.update(_classdir(obj.__class__))
+        except AttributeError:
+            pass
+        result = list(Dict.keys())
+        return result
+    """)
+    return w_result
+
 def descr__str__(space, w_obj):
     w_type = space.type(w_obj)
     w_impl = w_type.lookup("__repr__")
@@ -219,6 +253,7 @@
     __delattr__ = gateway.interp2app(Object.descr__delattr__.im_func),
     __str__ = gateway.interp2app(descr__str__),
     __repr__ = gateway.interp2app(descr__repr__),
+    __dir__ = gateway.interp2app(descr__dir__),
     __class__ = GetSetProperty(descr__class__, descr_set___class__),
     __doc__ = '''The most base type''',
     __new__ = gateway.interp2app(descr__new__),
diff --git a/pypy/objspace/std/test/test_obj.py 
b/pypy/objspace/std/test/test_obj.py
--- a/pypy/objspace/std/test/test_obj.py
+++ b/pypy/objspace/std/test/test_obj.py
@@ -105,6 +105,16 @@
                 return 123456
         assert A().__str__() == 123456
 
+    def test_object_dir(self):
+        class A(object):
+            a_var = None
+
+        assert hasattr(object, '__dir__')
+        obj = A()
+        obj_items = dir(obj)
+        assert obj_items == sorted(obj_items)
+        assert obj_items == sorted(object.__dir__(obj))
+
 
     def test_is_on_primitives(self):
         if self.cpython_apptest:
diff --git a/pypy/objspace/std/test/test_typeobject.py 
b/pypy/objspace/std/test/test_typeobject.py
--- a/pypy/objspace/std/test/test_typeobject.py
+++ b/pypy/objspace/std/test/test_typeobject.py
@@ -716,6 +716,25 @@
             pass
         raises(TypeError, "class D(A, C): pass")
 
+    def test_dir(self):
+        class A(object):
+            a_var = None
+            def a_meth(self):
+                pass
+
+        class C(A):
+            c_var = None
+            def c_meth(self):
+                pass
+
+        C_items = dir(C)
+        assert C_items != C.__dir__(C)  # as in cpython
+
+        assert 'a_var' in C_items
+        assert 'c_var' in C_items
+        assert 'a_meth' in C_items
+        assert 'c_meth' in C_items
+
     def test_data_descriptor_without_get(self):
         """
         class Descr(object):
diff --git a/pypy/objspace/std/typeobject.py b/pypy/objspace/std/typeobject.py
--- a/pypy/objspace/std/typeobject.py
+++ b/pypy/objspace/std/typeobject.py
@@ -730,6 +730,30 @@
     else:
         return space.get(w_result, space.w_None, w_type)
 
+def descr__dir(space, w_type):
+    w_result = space.appexec([w_type], """(obj):
+        def _classdir(klass):
+            Dict = {}
+            try:
+                Dict.update(klass.__dict__)
+            except AttributeError: pass
+            try:
+                bases = klass.__mro__
+            except AttributeError: pass
+            else:
+                try:
+                    #Note that since we are only interested in the keys,
+                    #  the order we merge classes is unimportant
+                    for base in bases:
+                        Dict.update(base.__dict__)
+                except TypeError: pass
+            return Dict
+
+        result = list(_classdir(obj).keys())
+        return result
+    """)
+    return w_result
+
 def descr__flags(space, w_type):
     from copy_reg import _HEAPTYPE
     _CPYTYPE = 1 # used for non-heap types defined in C
@@ -803,6 +827,7 @@
     __mro__ = GetSetProperty(descr_get__mro__),
     __dict__ = GetSetProperty(descr_get_dict),
     __doc__ = GetSetProperty(descr__doc),
+    __dir__ = gateway.interp2app(descr__dir),
     mro = gateway.interp2app(descr_mro),
     __flags__ = GetSetProperty(descr__flags),
     __module__ = GetSetProperty(descr_get__module, descr_set__module),
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to