[Python-checkins] bpo-46103: Fix inspect.getmembers to only get __bases__ from class (GH-30147)
ethanfurman
webhook-mailer at python.org
Sun Jan 23 12:40:43 EST 2022
https://github.com/python/cpython/commit/691506f4e9408a1205166f99640946ad7822e302
commit: 691506f4e9408a1205166f99640946ad7822e302
branch: main
author: Weipeng Hong <hongweichen8888 at sina.com>
committer: ethanfurman <ethan at stoneleaf.us>
date: 2022-01-23T09:40:38-08:00
summary:
bpo-46103: Fix inspect.getmembers to only get __bases__ from class (GH-30147)
files:
A Misc/NEWS.d/next/Library/2021-12-16-23-42-54.bpo-46103.LMnZAN.rst
M Lib/inspect.py
M Lib/test/test_inspect.py
diff --git a/Lib/inspect.py b/Lib/inspect.py
index 879a577d43fbe..d47f5b717471c 100644
--- a/Lib/inspect.py
+++ b/Lib/inspect.py
@@ -540,23 +540,23 @@ def isabstract(object):
return False
def _getmembers(object, predicate, getter):
+ results = []
+ processed = set()
+ names = dir(object)
if isclass(object):
mro = (object,) + getmro(object)
+ # add any DynamicClassAttributes to the list of names if object is a class;
+ # this may result in duplicate entries if, for example, a virtual
+ # attribute with the same name as a DynamicClassAttribute exists
+ try:
+ for base in object.__bases__:
+ for k, v in base.__dict__.items():
+ if isinstance(v, types.DynamicClassAttribute):
+ names.append(k)
+ except AttributeError:
+ pass
else:
mro = ()
- results = []
- processed = set()
- names = dir(object)
- # :dd any DynamicClassAttributes to the list of names if object is a class;
- # this may result in duplicate entries if, for example, a virtual
- # attribute with the same name as a DynamicClassAttribute exists
- try:
- for base in object.__bases__:
- for k, v in base.__dict__.items():
- if isinstance(v, types.DynamicClassAttribute):
- names.append(k)
- except AttributeError:
- pass
for key in names:
# First try to get the value via getattr. Some descriptors don't
# like calling their __get__ (see bug #1785), so fall back to
diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py
index cdbb9eb6a8f7c..76fa6f7e2dab8 100644
--- a/Lib/test/test_inspect.py
+++ b/Lib/test/test_inspect.py
@@ -1215,8 +1215,13 @@ class A(metaclass=M):
@types.DynamicClassAttribute
def eggs(self):
return 'spam'
+ class B:
+ def __getattr__(self, attribute):
+ return None
self.assertIn(('eggs', 'scrambled'), inspect.getmembers(A))
self.assertIn(('eggs', 'spam'), inspect.getmembers(A()))
+ b = B()
+ self.assertIn(('__getattr__', b.__getattr__), inspect.getmembers(b))
def test_getmembers_static(self):
class A:
diff --git a/Misc/NEWS.d/next/Library/2021-12-16-23-42-54.bpo-46103.LMnZAN.rst b/Misc/NEWS.d/next/Library/2021-12-16-23-42-54.bpo-46103.LMnZAN.rst
new file mode 100644
index 0000000000000..3becbc3de8fc2
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2021-12-16-23-42-54.bpo-46103.LMnZAN.rst
@@ -0,0 +1,2 @@
+Now :func:`inspect.getmembers` only gets :attr:`__bases__` attribute from
+class type. Patch by Weipeng Hong.
More information about the Python-checkins
mailing list