Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added docstring checker test #11

Merged
merged 8 commits into from
Oct 22, 2023
Merged
126 changes: 126 additions & 0 deletions tests/test_docstrings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import inspect
from types import ModuleType, FunctionType
from typing import List
import pytest
import roiextractors


def traverse_class(class_object: type, parent: str) -> List[FunctionType]:
"""Traverse the class dictionary and return the methods overridden by this module.

Parameters
----------
class_object : type
The class to traverse.
parent : str
The parent package name.

Returns
-------
class_methods : List[FunctionType]
A list of all methods defined in the given class.
"""
class_methods = []
for attribute_name, attribute_value in class_object.__dict__.items():
if isinstance(attribute_value, FunctionType) and attribute_value.__module__.startswith(parent):
if attribute_name.startswith("__") and attribute_name.endswith("__"):
continue
class_methods.append(attribute_value)
return class_methods


def traverse_module(module: ModuleType, parent: str) -> List:
"""Traverse the module and return all classes and functions defined along the way.

Parameters
----------
module : ModuleType
The module to traverse.
parent : str
The parent package name.

Returns
-------
local_classes_and_functions : List
A list of all classes and functions defined in the given module.
"""
local_classes_and_functions = []

for name in dir(module):
if name.startswith("__") and name.endswith("__"): # skip all magic methods
continue

object_ = getattr(module, name)

if isinstance(object_, type) and object_.__module__.startswith(parent): # class
class_object = object_
class_functions = traverse_class(class_object=class_object, parent=parent)
local_classes_and_functions.append(class_object)
local_classes_and_functions.extend(class_functions)

elif isinstance(object_, FunctionType) and object_.__module__.startswith(parent):
function = object_
local_classes_and_functions.append(function)

return local_classes_and_functions


def traverse_package(package: ModuleType, parent: str) -> List[ModuleType]:
"""Traverse the package and return all subpackages and modules defined along the way.

Parameters
----------
package : ModuleType
The package, subpackage, or module to traverse.
parent : str
The parent package name.

Returns
-------
local_packages_and_modules : List[ModuleType]
A list of all subpackages and modules defined in the given package.
"""
local_packages_and_modules = []

for name in dir(package):
if name.startswith("__") and name.endswith("__"): # skip all magic methods
continue

object_ = getattr(package, name)

if (
isinstance(object_, ModuleType)
and object_.__file__[-11:] == "__init__.py"
and object_.__package__.startswith(parent)
):
subpackage = object_
subpackage_members = traverse_package(package=subpackage, parent=parent)
local_packages_and_modules.append(subpackage)
local_packages_and_modules.extend(subpackage_members)

elif isinstance(object_, ModuleType) and object_.__package__.startswith(parent):
module = object_
module_members = traverse_module(module=module, parent=parent)
local_packages_and_modules.append(module)
local_packages_and_modules.extend(module_members)

return local_packages_and_modules


objs = traverse_package(roiextractors, "roiextractors")


@pytest.mark.parametrize("obj", objs)
def test_has_docstring(obj):
"""Check if an object has a docstring."""
doc = inspect.getdoc(obj)
if inspect.ismodule(obj):
msg = f"{obj.__name__} has no docstring."
else:
msg = f"{obj.__module__}.{obj.__qualname__} has no docstring."
assert doc is not None, msg
CodyCBakerPhD marked this conversation as resolved.
Show resolved Hide resolved


if __name__ == "__main__":
for obj in objs:
test_has_docstring(obj)