@@ -174,6 +174,18 @@ def is_method(self) -> bool:
174
174
function_type = type (lambda : None )
175
175
return self .parent_is_class () and isinstance (self .obj , function_type )
176
176
177
+ def is_method_descriptor (self ) -> bool :
178
+ """
179
+ Tell if this node's object is a method descriptor.
180
+
181
+ Built-in methods (e.g. those implemented in C/Rust) are often
182
+ method descriptors, rather than normal methods.
183
+
184
+ Returns:
185
+ If this node's object is a method descriptor.
186
+ """
187
+ return inspect .ismethoddescriptor (self .obj )
188
+
177
189
def is_staticmethod (self ) -> bool :
178
190
"""
179
191
Tell if this node's object is a staticmethod.
@@ -361,6 +373,8 @@ def get_object_documentation(self, dotted_path: str, members: Optional[Union[Set
361
373
root_object = self .get_staticmethod_documentation (leaf )
362
374
elif leaf .is_classmethod ():
363
375
root_object = self .get_classmethod_documentation (leaf )
376
+ elif leaf .is_method_descriptor ():
377
+ root_object = self .get_regular_method_documentation (leaf )
364
378
elif leaf .is_method ():
365
379
root_object = self .get_regular_method_documentation (leaf )
366
380
elif leaf .is_function ():
@@ -836,7 +850,7 @@ def get_regular_method_documentation(self, node: ObjectNode) -> Method:
836
850
837
851
def get_method_documentation (self , node : ObjectNode , properties : Optional [List [str ]] = None ) -> Method :
838
852
"""
839
- Get the documentation for a method.
853
+ Get the documentation for a method or method descriptor .
840
854
841
855
Arguments:
842
856
node: The node representing the method and its parents.
@@ -847,6 +861,7 @@ def get_method_documentation(self, node: ObjectNode, properties: Optional[List[s
847
861
"""
848
862
method = node .obj
849
863
path = node .dotted_path
864
+ signature : Optional [inspect .Signature ]
850
865
source : Optional [Source ]
851
866
852
867
try :
@@ -863,12 +878,23 @@ def get_method_documentation(self, node: ObjectNode, properties: Optional[List[s
863
878
else :
864
879
properties .append ("async" )
865
880
881
+ try :
882
+ # for "built-in" functions, e.g. those implemented in C,
883
+ # inspect.signature() uses the __text_signature__ attribute, which
884
+ # provides a limited but still useful amount of signature information.
885
+ # "built-in" functions with no __text_signature__ will
886
+ # raise a ValueError().
887
+ signature = inspect .signature (method )
888
+ except ValueError as error :
889
+ self .errors .append (f"Couldn't read signature for '{ path } ': { error } " )
890
+ signature = None
891
+
866
892
return Method (
867
893
name = node .name ,
868
894
path = path ,
869
895
file_path = node .file_path ,
870
896
docstring = inspect .getdoc (method ),
871
- signature = inspect . signature ( method ) ,
897
+ signature = signature ,
872
898
properties = properties or [],
873
899
source = source ,
874
900
)
0 commit comments