@@ -174,6 +174,18 @@ def is_method(self) -> bool:
174174 function_type = type (lambda : None )
175175 return self .parent_is_class () and isinstance (self .obj , function_type )
176176
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+
177189 def is_staticmethod (self ) -> bool :
178190 """
179191 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
361373 root_object = self .get_staticmethod_documentation (leaf )
362374 elif leaf .is_classmethod ():
363375 root_object = self .get_classmethod_documentation (leaf )
376+ elif leaf .is_method_descriptor ():
377+ root_object = self .get_regular_method_documentation (leaf )
364378 elif leaf .is_method ():
365379 root_object = self .get_regular_method_documentation (leaf )
366380 elif leaf .is_function ():
@@ -836,7 +850,7 @@ def get_regular_method_documentation(self, node: ObjectNode) -> Method:
836850
837851 def get_method_documentation (self , node : ObjectNode , properties : Optional [List [str ]] = None ) -> Method :
838852 """
839- Get the documentation for a method.
853+ Get the documentation for a method or method descriptor .
840854
841855 Arguments:
842856 node: The node representing the method and its parents.
@@ -847,6 +861,7 @@ def get_method_documentation(self, node: ObjectNode, properties: Optional[List[s
847861 """
848862 method = node .obj
849863 path = node .dotted_path
864+ signature : Optional [inspect .Signature ]
850865 source : Optional [Source ]
851866
852867 try :
@@ -863,12 +878,23 @@ def get_method_documentation(self, node: ObjectNode, properties: Optional[List[s
863878 else :
864879 properties .append ("async" )
865880
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+
866892 return Method (
867893 name = node .name ,
868894 path = path ,
869895 file_path = node .file_path ,
870896 docstring = inspect .getdoc (method ),
871- signature = inspect . signature ( method ) ,
897+ signature = signature ,
872898 properties = properties or [],
873899 source = source ,
874900 )
0 commit comments