Skip to content

Commit a97f676

Browse files
author
Joel Gibson
committed
feat: Allow method_descriptors to be serialized as methods
1 parent c4b58a6 commit a97f676

File tree

1 file changed

+28
-2
lines changed

1 file changed

+28
-2
lines changed

src/pytkdocs/loader.py

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,18 @@ def is_method(self) -> bool:
173173
function_type = type(lambda: None)
174174
return self.parent_is_class() and isinstance(self.obj, function_type)
175175

176+
def is_method_descriptor(self) -> bool:
177+
"""
178+
Tell if this node's object is a method descriptor.
179+
180+
Built-in methods (e.g. those implemented in C/Rust) are often
181+
method descriptors, rather than normal methods.
182+
183+
Returns:
184+
If this node's object is a method descriptor.
185+
"""
186+
return inspect.ismethoddescriptor(self.obj)
187+
176188
def is_staticmethod(self) -> bool:
177189
"""
178190
Tell if this node's object is a staticmethod.
@@ -360,6 +372,8 @@ def get_object_documentation(self, dotted_path: str, members: Optional[Union[Set
360372
root_object = self.get_staticmethod_documentation(leaf)
361373
elif leaf.is_classmethod():
362374
root_object = self.get_classmethod_documentation(leaf)
375+
elif leaf.is_method_descriptor():
376+
root_object = self.get_regular_method_documentation(leaf)
363377
elif leaf.is_method():
364378
root_object = self.get_regular_method_documentation(leaf)
365379
elif leaf.is_function():
@@ -792,7 +806,7 @@ def get_regular_method_documentation(self, node: ObjectNode) -> Method:
792806

793807
def get_method_documentation(self, node: ObjectNode, properties: Optional[List[str]] = None) -> Method:
794808
"""
795-
Get the documentation for a method.
809+
Get the documentation for a method or method descriptor.
796810
797811
Arguments:
798812
node: The node representing the method and its parents.
@@ -803,6 +817,7 @@ def get_method_documentation(self, node: ObjectNode, properties: Optional[List[s
803817
"""
804818
method = node.obj
805819
path = node.dotted_path
820+
signature: Optional[inspect.Signature]
806821
source: Optional[Source]
807822

808823
try:
@@ -819,12 +834,23 @@ def get_method_documentation(self, node: ObjectNode, properties: Optional[List[s
819834
else:
820835
properties.append("async")
821836

837+
try:
838+
# for "built-in" functions, e.g. those implemented in C,
839+
# inspect.signature() uses the __text_signature__ attribute, which
840+
# provides a limited but still useful amount of signature information.
841+
# "built-in" functions with no __text_signature__ will
842+
# raise a ValueError().
843+
signature = inspect.signature(method)
844+
except ValueError as error:
845+
self.errors.append(f"Couldn't read signature for '{path}': {error}")
846+
signature = None
847+
822848
return Method(
823849
name=node.name,
824850
path=path,
825851
file_path=node.file_path,
826852
docstring=inspect.getdoc(method),
827-
signature=inspect.signature(method),
853+
signature=signature,
828854
properties=properties or [],
829855
source=source,
830856
)

0 commit comments

Comments
 (0)