Backport from Py3k branch:
Patch #1591665: implement the __dir__() special function lookup in PyObject_Dir.
Had to change a few bits of the patch because classobjs and __methods__ are still
in Py2.6.
diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py
index da2afba..333e01e 100644
--- a/Lib/test/test_builtin.py
+++ b/Lib/test/test_builtin.py
@@ -259,12 +259,67 @@
self.assertRaises(TypeError, delattr)
def test_dir(self):
- x = 1
- self.assert_('x' in dir())
- import sys
- self.assert_('modules' in dir(sys))
+ # dir(wrong number of arguments)
self.assertRaises(TypeError, dir, 42, 42)
+ # dir() - local scope
+ local_var = 1
+ self.assert_('local_var' in dir())
+
+ # dir(module)
+ import sys
+ self.assert_('exit' in dir(sys))
+
+ # dir(module_with_invalid__dict__)
+ import types
+ class Foo(types.ModuleType):
+ __dict__ = 8
+ f = Foo("foo")
+ self.assertRaises(TypeError, dir, f)
+
+ # dir(type)
+ self.assert_("strip" in dir(str))
+ self.assert_("__mro__" not in dir(str))
+
+ # dir(obj)
+ class Foo(object):
+ def __init__(self):
+ self.x = 7
+ self.y = 8
+ self.z = 9
+ f = Foo()
+ self.assert_("y" in dir(f))
+
+ # dir(obj_no__dict__)
+ class Foo(object):
+ __slots__ = []
+ f = Foo()
+ self.assert_("__repr__" in dir(f))
+
+ # dir(obj_no__class__with__dict__)
+ # (an ugly trick to cause getattr(f, "__class__") to fail)
+ class Foo(object):
+ __slots__ = ["__class__", "__dict__"]
+ def __init__(self):
+ self.bar = "wow"
+ f = Foo()
+ self.assert_("__repr__" not in dir(f))
+ self.assert_("bar" in dir(f))
+
+ # dir(obj_using __dir__)
+ class Foo(object):
+ def __dir__(self):
+ return ["kan", "ga", "roo"]
+ f = Foo()
+ self.assert_(dir(f) == ["ga", "kan", "roo"])
+
+ # dir(obj__dir__not_list)
+ class Foo(object):
+ def __dir__(self):
+ return 7
+ f = Foo()
+ self.assertRaises(TypeError, dir, f)
+
def test_divmod(self):
self.assertEqual(divmod(12, 7), (1, 5))
self.assertEqual(divmod(-12, 7), (-2, 2))