]> granicus.if.org Git - python/commitdiff
Revert part of 13f56cd8dec1 (issue #1785) to avoid breaking getmembers() with unbound...
authorAntoine Pitrou <solipsis@pitrou.net>
Wed, 18 Jan 2012 16:39:01 +0000 (17:39 +0100)
committerAntoine Pitrou <solipsis@pitrou.net>
Wed, 18 Jan 2012 16:39:01 +0000 (17:39 +0100)
Python 3 isn't affected (unbound methods don't exist).
Thanks to Vincent Pelletier for noticing.

Lib/inspect.py
Lib/test/test_inspect.py

index cb07b9d9ab1ef11e8bec1787116107bea3e1abd0..66d51865734ab0b6bf534d9ea36d561ffa3755e4 100644 (file)
@@ -247,23 +247,12 @@ def isabstract(object):
 def getmembers(object, predicate=None):
     """Return all members of an object as (name, value) pairs sorted by name.
     Optionally, only return members that satisfy a given predicate."""
-    if isclass(object):
-        mro = (object,) + getmro(object)
-    else:
-        mro = ()
     results = []
     for key in dir(object):
-        # First try to get the value via __dict__. Some descriptors don't
-        # like calling their __get__ (see bug #1785).
-        for base in mro:
-            if key in base.__dict__:
-                value = base.__dict__[key]
-                break
-        else:
-            try:
-                value = getattr(object, key)
-            except AttributeError:
-                continue
+        try:
+            value = getattr(object, key)
+        except AttributeError:
+            continue
         if not predicate or predicate(value):
             results.append((key, value))
     results.sort()
index 97de7a07286dc3a487f5b07b9a72c2a94e039961..30b1556cbfbb1908dcb2763a57ba6c1491e3cf3f 100644 (file)
@@ -600,56 +600,30 @@ class TestClassesAndFunctions(unittest.TestCase):
             if isinstance(builtin, type):
                 inspect.classify_class_attrs(builtin)
 
-    def test_getmembers_descriptors(self):
+    def test_getmembers_method(self):
         # Old-style classes
-        class A:
-            dd = _BrokenDataDescriptor()
-            md = _BrokenMethodDescriptor()
-
-        self.assertEqual(inspect.getmembers(A, inspect.ismethoddescriptor),
-            [('md', A.__dict__['md'])])
-        self.assertEqual(inspect.getmembers(A, inspect.isdatadescriptor),
-            [('dd', A.__dict__['dd'])])
-
-        class B(A):
-            pass
+        class B:
+            def f(self):
+                pass
 
-        self.assertEqual(inspect.getmembers(B, inspect.ismethoddescriptor),
-            [('md', A.__dict__['md'])])
-        self.assertEqual(inspect.getmembers(B, inspect.isdatadescriptor),
-            [('dd', A.__dict__['dd'])])
+        self.assertIn(('f', B.f), inspect.getmembers(B))
+        # contrary to spec, ismethod() is also True for unbound methods
+        # (see #1785)
+        self.assertIn(('f', B.f), inspect.getmembers(B, inspect.ismethod))
+        b = B()
+        self.assertIn(('f', b.f), inspect.getmembers(b))
+        self.assertIn(('f', b.f), inspect.getmembers(b, inspect.ismethod))
 
         # New-style classes
-        class A(object):
-            dd = _BrokenDataDescriptor()
-            md = _BrokenMethodDescriptor()
-
-        def pred_wrapper(pred):
-            # A quick'n'dirty way to discard standard attributes of new-style
-            # classes.
-            class Empty(object):
+        class B(object):
+            def f(self):
                 pass
-            def wrapped(x):
-                if hasattr(x, '__name__') and hasattr(Empty, x.__name__):
-                    return False
-                return pred(x)
-            return wrapped
-
-        ismethoddescriptor = pred_wrapper(inspect.ismethoddescriptor)
-        isdatadescriptor = pred_wrapper(inspect.isdatadescriptor)
-
-        self.assertEqual(inspect.getmembers(A, ismethoddescriptor),
-            [('md', A.__dict__['md'])])
-        self.assertEqual(inspect.getmembers(A, isdatadescriptor),
-            [('dd', A.__dict__['dd'])])
-
-        class B(A):
-            pass
 
-        self.assertEqual(inspect.getmembers(B, ismethoddescriptor),
-            [('md', A.__dict__['md'])])
-        self.assertEqual(inspect.getmembers(B, isdatadescriptor),
-            [('dd', A.__dict__['dd'])])
+        self.assertIn(('f', B.f), inspect.getmembers(B))
+        self.assertIn(('f', B.f), inspect.getmembers(B, inspect.ismethod))
+        b = B()
+        self.assertIn(('f', b.f), inspect.getmembers(b))
+        self.assertIn(('f', b.f), inspect.getmembers(b, inspect.ismethod))
 
 
 class TestGetcallargsFunctions(unittest.TestCase):