[pypy-commit] pypy py3.3: __dir__ is allowed to return any iterable like in cpython3.

kvas noreply at buildbot.pypy.org
Sat Jul 26 12:32:34 CEST 2014


Author: Vasily Kuznetsov <kvas.it at gmail.com>
Branch: py3.3
Changeset: r72492:72a3a7810d5c
Date: 2014-07-26 12:05 +0200
http://bitbucket.org/pypy/pypy/changeset/72a3a7810d5c/

Log:	__dir__ is allowed to return any iterable like in cpython3.

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
@@ -52,11 +52,8 @@
     dir_meth = lookup_special(obj, "__dir__")
     if dir_meth is not None:
         result = dir_meth()
-        if isinstance(result, tuple):
-            result = list(result)
         if not isinstance(result, list):
-            raise TypeError("__dir__() must return a list, not %r" % (
-                type(result),))
+            result = list(result)  # Will throw TypeError if not iterable
         result.sort()
         return result
     elif isinstance(obj, types.ModuleType):
diff --git a/pypy/module/__builtin__/test/test_dir.py b/pypy/module/__builtin__/test/test_dir.py
--- a/pypy/module/__builtin__/test/test_dir.py
+++ b/pypy/module/__builtin__/test/test_dir.py
@@ -1,12 +1,26 @@
 class AppTestDir:
 
     def test_dir_obj__dir__tuple(self):
-        """When __dir__ method returns a tuple, python3 converts it to list."""
-
+        """If __dir__ method returns a tuple, cpython3 converts it to list."""
         class Foo(object):
             def __dir__(self):
                 return ("b", "c", "a")
-
         res = dir(Foo())
         assert isinstance(res, list)
         assert res == ["a", "b", "c"]
+
+    def test_dir_obj__dir__genexp(self):
+        """Generator expression is also converted to list by cpython3."""
+        class Foo(object):
+            def __dir__(self):
+                return (i for i in ["b", "c", "a"])
+        res = dir(Foo())
+        assert isinstance(res, list)
+        assert res == ["a", "b", "c"]
+
+    def test_dir_obj__dir__noniter(self):
+        """If result of __dir__ is not iterable, it's an error."""
+        class Foo(object):
+            def __dir__(self):
+                return 42
+        raises(TypeError, dir, Foo())


More information about the pypy-commit mailing list