Skip to content

Commit

Permalink
feat: Add async property for coroutine functions
Browse files Browse the repository at this point in the history
Feature request: mkdocstrings/mkdocstrings#151.
Pull request: ghpr-65.
  • Loading branch information
art049 authored Sep 15, 2020
1 parent 229d7d2 commit a013c07
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 0 deletions.
15 changes: 15 additions & 0 deletions src/pytkdocs/loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ def is_function(self) -> bool:
"""Is this node's object a function?"""
return inspect.isfunction(self.obj)

def is_coroutine_function(self) -> bool:
"""Is this node's object a coroutine?"""
return inspect.iscoroutinefunction(self.obj)

def is_property(self) -> bool:
"""Is this node's object a property?"""
return isinstance(self.obj, property)
Expand Down Expand Up @@ -460,13 +464,18 @@ def get_function_documentation(self, node: ObjectNode) -> Function:
self.errors.append(f"Couldn't read source for '{path}': {error}")
source = None

properties: List[str] = []
if node.is_coroutine_function():
properties.append("async")

return Function(
name=node.name,
path=node.dotted_path,
file_path=node.file_path,
docstring=inspect.getdoc(function),
signature=signature,
source=source,
properties=properties,
)

def get_property_documentation(self, node: ObjectNode) -> Attribute:
Expand Down Expand Up @@ -664,6 +673,12 @@ def get_method_documentation(self, node: ObjectNode, properties: Optional[List[s
except TypeError:
source = None

if node.is_coroutine_function():
if properties is None:
properties = ["async"]
else:
properties.append("async")

return Method(
name=node.name,
path=path,
Expand Down
6 changes: 6 additions & 0 deletions tests/fixtures/asyncio.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class ClassContainingCoroutineMethod:
async def coroutine_method(self) -> None:
return

async def coroutine_function() -> None:
return
28 changes: 28 additions & 0 deletions tests/test_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -409,3 +409,31 @@ def test_unwrap_object_with_getattr_method_raising_exception():
"""Try loading an object that defines a `__getattr__` method which raises an exception."""
loader = Loader()
loader.get_object_documentation("tests.fixtures.unwrap_getattr_raises")


def test_loading_coroutine():
"""Load documentation for a coroutine."""
loader = Loader()
obj = loader.get_object_documentation("tests.fixtures.asyncio.coroutine_function")
assert "async" in obj.properties


def test_loading_coroutine_method():
"""Load documentation for a coroutine method."""
loader = Loader()
obj = loader.get_object_documentation("tests.fixtures.asyncio.ClassContainingCoroutineMethod.coroutine_method")
assert "async" in obj.properties


def test_loading_function_without_async_property():
"""Load documentation for a function that is not a coroutine."""
loader = Loader()
obj = loader.get_object_documentation("tests.fixtures.the_package.the_module.the_function")
assert "async" not in obj.properties


def test_loading_method_without_async_property():
"""Load documentation for a method that is not a coroutine."""
loader = Loader()
obj = loader.get_object_documentation("tests.fixtures.the_package.the_module.TheClass.the_method")
assert "async" not in obj.properties

0 comments on commit a013c07

Please sign in to comment.