cpython: f824744557ba (original) (raw)
--- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -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)[](#l1.8)
- else:
results = [] for key in dir(object):mro = ()[](#l1.10)
# First try to get the value via __dict__. Some descriptors don't[](#l1.13)
# like calling their __get__ (see bug #1785).[](#l1.14)
for base in mro:[](#l1.15)
if key in base.__dict__:[](#l1.16)
value = base.__dict__[key][](#l1.17)
break[](#l1.18)
else:[](#l1.19)
try:[](#l1.20)
value = getattr(object, key)[](#l1.21)
except AttributeError:[](#l1.22)
continue[](#l1.23)
try:[](#l1.24)
value = getattr(object, key)[](#l1.25)
except AttributeError:[](#l1.26)
results.sort()continue[](#l1.27) if not predicate or predicate(value):[](#l1.28) results.append((key, value))[](#l1.29)
--- a/Lib/test/test_inspect.py +++ b/Lib/test/test_inspect.py @@ -600,56 +600,30 @@ class TestClassesAndFunctions(unittest.T if isinstance(builtin, type): inspect.classify_class_attrs(builtin)
class A:[](#l2.10)
dd = _BrokenDataDescriptor()[](#l2.11)
md = _BrokenMethodDescriptor()[](#l2.12)
class B:[](#l2.13)
def f(self):[](#l2.14)
pass[](#l2.15)
self.assertEqual(inspect.getmembers(A, inspect.ismethoddescriptor),[](#l2.17)
[('md', A.__dict__['md'])])[](#l2.18)
self.assertEqual(inspect.getmembers(A, inspect.isdatadescriptor),[](#l2.19)
[('dd', A.__dict__['dd'])])[](#l2.20)
class B(A):[](#l2.22)
pass[](#l2.23)
self.assertEqual(inspect.getmembers(B, inspect.ismethoddescriptor),[](#l2.25)
[('md', A.__dict__['md'])])[](#l2.26)
self.assertEqual(inspect.getmembers(B, inspect.isdatadescriptor),[](#l2.27)
[('dd', A.__dict__['dd'])])[](#l2.28)
self.assertIn(('f', B.f), inspect.getmembers(B))[](#l2.29)
# contrary to spec, ismethod() is also True for unbound methods[](#l2.30)
# (see #1785)[](#l2.31)
self.assertIn(('f', B.f), inspect.getmembers(B, inspect.ismethod))[](#l2.32)
b = B()[](#l2.33)
self.assertIn(('f', b.f), inspect.getmembers(b))[](#l2.34)
self.assertIn(('f', b.f), inspect.getmembers(b, inspect.ismethod))[](#l2.35)
class A(object):[](#l2.38)
dd = _BrokenDataDescriptor()[](#l2.39)
md = _BrokenMethodDescriptor()[](#l2.40)
def pred_wrapper(pred):[](#l2.42)
# A quick'n'dirty way to discard standard attributes of new-style[](#l2.43)
# classes.[](#l2.44)
class Empty(object):[](#l2.45)
class B(object):[](#l2.46)
def f(self):[](#l2.47) pass[](#l2.48)
def wrapped(x):[](#l2.49)
if hasattr(x, '__name__') and hasattr(Empty, x.__name__):[](#l2.50)
return False[](#l2.51)
return pred(x)[](#l2.52)
return wrapped[](#l2.53)
ismethoddescriptor = pred_wrapper(inspect.ismethoddescriptor)[](#l2.55)
isdatadescriptor = pred_wrapper(inspect.isdatadescriptor)[](#l2.56)
self.assertEqual(inspect.getmembers(A, ismethoddescriptor),[](#l2.58)
[('md', A.__dict__['md'])])[](#l2.59)
self.assertEqual(inspect.getmembers(A, isdatadescriptor),[](#l2.60)
[('dd', A.__dict__['dd'])])[](#l2.61)
class B(A):[](#l2.63)
pass[](#l2.64)
self.assertEqual(inspect.getmembers(B, ismethoddescriptor),[](#l2.66)
[('md', A.__dict__['md'])])[](#l2.67)
self.assertEqual(inspect.getmembers(B, isdatadescriptor),[](#l2.68)
[('dd', A.__dict__['dd'])])[](#l2.69)
self.assertIn(('f', B.f), inspect.getmembers(B))[](#l2.70)
self.assertIn(('f', B.f), inspect.getmembers(B, inspect.ismethod))[](#l2.71)
b = B()[](#l2.72)
self.assertIn(('f', b.f), inspect.getmembers(b))[](#l2.73)
self.assertIn(('f', b.f), inspect.getmembers(b, inspect.ismethod))[](#l2.74)