From 34ece7762916feb4e288a0726817cc0e3ef23fb8 Mon Sep 17 00:00:00 2001 From: Arthur Pastel Date: Tue, 15 Sep 2020 01:16:07 +0200 Subject: [PATCH] feat: add async property for coroutine functions --- src/pytkdocs/loader.py | 15 +++++++++++++++ tests/fixtures/asyncio.py | 6 ++++++ tests/test_loader.py | 28 ++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+) create mode 100644 tests/fixtures/asyncio.py diff --git a/src/pytkdocs/loader.py b/src/pytkdocs/loader.py index 4041824..2664169 100644 --- a/src/pytkdocs/loader.py +++ b/src/pytkdocs/loader.py @@ -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) @@ -460,6 +464,10 @@ 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, @@ -467,6 +475,7 @@ def get_function_documentation(self, node: ObjectNode) -> Function: docstring=inspect.getdoc(function), signature=signature, source=source, + properties=properties, ) def get_property_documentation(self, node: ObjectNode) -> Attribute: @@ -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, diff --git a/tests/fixtures/asyncio.py b/tests/fixtures/asyncio.py new file mode 100644 index 0000000..e73c466 --- /dev/null +++ b/tests/fixtures/asyncio.py @@ -0,0 +1,6 @@ +class ClassContainingCoroutineMethod: + async def coroutine_method(self) -> None: + return + +async def coroutine_function() -> None: + return diff --git a/tests/test_loader.py b/tests/test_loader.py index db8678f..17dde3c 100644 --- a/tests/test_loader.py +++ b/tests/test_loader.py @@ -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