[Python-checkins] cpython (2.7): Revert part of 13f56cd8dec1 (issue #1785) to avoid breaking getmembers() with

antoine.pitrou python-checkins at python.org
Wed Jan 18 17:41:02 CET 2012


http://hg.python.org/cpython/rev/f824744557ba
changeset:   74501:f824744557ba
branch:      2.7
parent:      74488:4074439c3894
user:        Antoine Pitrou <solipsis at pitrou.net>
date:        Wed Jan 18 17:39:01 2012 +0100
summary:
  Revert part of 13f56cd8dec1 (issue #1785) to avoid breaking getmembers() with unbound methods.
Python 3 isn't affected (unbound methods don't exist).
Thanks to Vincent Pelletier for noticing.

files:
  Lib/inspect.py           |  19 +------
  Lib/test/test_inspect.py |  64 ++++++++-------------------
  2 files changed, 23 insertions(+), 60 deletions(-)


diff --git a/Lib/inspect.py b/Lib/inspect.py
--- a/Lib/inspect.py
+++ b/Lib/inspect.py
@@ -247,23 +247,12 @@
 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()
diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py
--- a/Lib/test/test_inspect.py
+++ b/Lib/test/test_inspect.py
@@ -600,56 +600,30 @@
             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()
+        class B:
+            def f(self):
+                pass
 
-        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
-
-        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()
+        class B(object):
+            def f(self):
+                pass
 
-        def pred_wrapper(pred):
-            # A quick'n'dirty way to discard standard attributes of new-style
-            # classes.
-            class Empty(object):
-                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):

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list