Skip to content

Commit 3327a2d

Browse files
bpo-32265: Classify class and static methods of builtin types. (#4776)
Add types.ClassMethodDescriptorType for unbound class methods.
1 parent 2e3f570 commit 3327a2d

File tree

6 files changed

+32
-3
lines changed

6 files changed

+32
-3
lines changed

Doc/library/types.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,14 @@ Standard names are defined for the following types:
155155
.. versionadded:: 3.7
156156

157157

158+
.. data:: ClassMethodDescriptorType
159+
160+
The type of *unbound* class methods of some built-in data types such as
161+
``dict.__dict__['fromkeys']``.
162+
163+
.. versionadded:: 3.7
164+
165+
158166
.. class:: ModuleType(name, doc=None)
159167

160168
The type of :term:`modules <module>`. Constructor takes the name of the

Lib/inspect.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -457,10 +457,10 @@ def classify_class_attrs(cls):
457457
continue
458458
obj = get_obj if get_obj is not None else dict_obj
459459
# Classify the object or its descriptor.
460-
if isinstance(dict_obj, staticmethod):
460+
if isinstance(dict_obj, (staticmethod, types.BuiltinMethodType)):
461461
kind = "static method"
462462
obj = dict_obj
463-
elif isinstance(dict_obj, classmethod):
463+
elif isinstance(dict_obj, (classmethod, types.ClassMethodDescriptorType)):
464464
kind = "class method"
465465
obj = dict_obj
466466
elif isinstance(dict_obj, property):

Lib/test/test_inspect.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -858,7 +858,8 @@ def m1(self): pass
858858

859859
attrs = attrs_wo_objs(A)
860860

861-
self.assertIn(('__new__', 'method', object), attrs, 'missing __new__')
861+
self.assertIn(('__new__', 'static method', object), attrs,
862+
'missing __new__')
862863
self.assertIn(('__init__', 'method', object), attrs, 'missing __init__')
863864

864865
self.assertIn(('s', 'static method', A), attrs, 'missing static method')
@@ -923,6 +924,18 @@ def test_classify_builtin_types(self):
923924
if isinstance(builtin, type):
924925
inspect.classify_class_attrs(builtin)
925926

927+
attrs = attrs_wo_objs(bool)
928+
self.assertIn(('__new__', 'static method', bool), attrs,
929+
'missing __new__')
930+
self.assertIn(('from_bytes', 'class method', int), attrs,
931+
'missing class method')
932+
self.assertIn(('to_bytes', 'method', int), attrs,
933+
'missing plain method')
934+
self.assertIn(('__add__', 'method', int), attrs,
935+
'missing plain method')
936+
self.assertIn(('__and__', 'method', bool), attrs,
937+
'missing plain method')
938+
926939
def test_classify_DynamicClassAttribute(self):
927940
class Meta(type):
928941
def __getattr__(self, name):

Lib/test/test_types.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,10 @@ def test_method_descriptor_types(self):
594594
self.assertIsInstance(''.join, types.BuiltinMethodType)
595595
self.assertIsInstance([].append, types.BuiltinMethodType)
596596

597+
self.assertIsInstance(int.__dict__['from_bytes'], types.ClassMethodDescriptorType)
598+
self.assertIsInstance(int.from_bytes, types.BuiltinMethodType)
599+
self.assertIsInstance(int.__new__, types.BuiltinMethodType)
600+
597601

598602
class MappingProxyTests(unittest.TestCase):
599603
mappingproxy = types.MappingProxyType

Lib/types.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ def _m(self): pass
3939
WrapperDescriptorType = type(object.__init__)
4040
MethodWrapperType = type(object().__str__)
4141
MethodDescriptorType = type(str.join)
42+
ClassMethodDescriptorType = type(dict.__dict__['fromkeys'])
4243

4344
ModuleType = type(sys)
4445

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
All class and static methods of builtin types now are correctly classified
2+
by inspect.classify_class_attrs() and grouped in pydoc ouput. Added
3+
types.ClassMethodDescriptorType for unbound class methods of builtin types.

0 commit comments

Comments
 (0)