d5dc737b86
git-subtree-dir: utils_v2 git-subtree-split: 97ea8e2eee0b34c9bf906d60cd7fe14b4ef82daa
178 lines
7.2 KiB
Python
178 lines
7.2 KiB
Python
"""
|
|
|
|
AUTHOR:
|
|
|
|
Khushal P Soonderji
|
|
|
|
DATE:
|
|
|
|
Saturday, 24th Aug., 2024
|
|
|
|
OBJECTIVE:
|
|
|
|
To provide an overview of any function or class in a string.
|
|
The generated overview can then either be shown on the terminal, or transmitted over some other medium for
|
|
collaborative work.
|
|
|
|
REFERENCES:
|
|
|
|
N/A
|
|
|
|
DOWNLOADS:
|
|
|
|
N/A
|
|
|
|
"""
|
|
|
|
|
|
# *****************************************************************************************************************
|
|
# ***** ****
|
|
# *** IMPORT ***
|
|
# ***** ****
|
|
# *****************************************************************************************************************
|
|
|
|
|
|
# System-level activities:
|
|
import io
|
|
import inspect
|
|
|
|
|
|
# *****************************************************************************************************************
|
|
# ***** ****
|
|
# *** MACROS / ONE-TIME INIT ***
|
|
# ***** ****
|
|
# *****************************************************************************************************************
|
|
|
|
|
|
# --- Nothing Yet
|
|
|
|
|
|
# *****************************************************************************************************************
|
|
# ***** ****
|
|
# *** VARIABLES ***
|
|
# ***** ****
|
|
# *****************************************************************************************************************
|
|
|
|
|
|
# --- Nothing Yet
|
|
|
|
|
|
# *****************************************************************************************************************
|
|
# ***** ****
|
|
# *** FUNCTIONS ***
|
|
# ***** ****
|
|
# *****************************************************************************************************************
|
|
|
|
|
|
def get_help_for_class(cls, skip_methods = None):
|
|
|
|
"""
|
|
Returns the help documentation to use this class.
|
|
:param cls: The class whose help string is desired.
|
|
:param skip_methods: A list of methods to NOT include in the help text.
|
|
:return: This help documentation.
|
|
"""
|
|
|
|
separator = "\n\n" + ("=" * 120) + "\n\n"
|
|
if skip_methods is None: skip_methods = []
|
|
elif not isinstance(skip_methods, list): skip_methods = [skip_methods]
|
|
|
|
# Get class name and docstring:
|
|
class_name = cls.__name__
|
|
docstring = inspect.getdoc(cls) or ""
|
|
help_string = "HELP FOR:\n\n"
|
|
help_string += class_name + "\n\n"
|
|
help_string += "This document has upto 120 chars per line.\n"
|
|
help_string += "Best viewed with monospaced font :)"
|
|
help_string += docstring + separator
|
|
|
|
# Get all methods and their docstrings.
|
|
# Then note the documentation of the methods while ignoring the blacklisted ones:
|
|
members = inspect.getmembers(cls, predicate = inspect.isfunction)
|
|
func_help = []
|
|
for name, method in members:
|
|
|
|
# Ignore if asked, or extract the details:
|
|
if name in skip_methods or name.startswith(f"_{class_name}__"): continue
|
|
else: func_help.append(get_help_for_function(method))
|
|
|
|
# Put all the things together:
|
|
func_help = separator.join(func_help)
|
|
help_string += func_help
|
|
|
|
# Done here:
|
|
return help_string
|
|
|
|
|
|
# ---------------------------------------------------------------------------------------------------------------------
|
|
|
|
|
|
def get_help_for_function(func):
|
|
|
|
"""
|
|
Get the help string for one function.
|
|
It could be a standalone function, or a method of a class.
|
|
:param func: The function (or method) whose help string is needed.
|
|
:return: The help string of the function.
|
|
"""
|
|
|
|
# Get the name and documentation:
|
|
func_name = func.__name__
|
|
async_indicator = " (async)" if inspect.iscoroutinefunction(func) else ""
|
|
func_doc = inspect.getdoc(func) or ""
|
|
|
|
# Create the decorated header:
|
|
func_decorator = "-" * (len(func_name) + 2)
|
|
func_head = "." + func_decorator + f".\n| {func_name} |{async_indicator}\n`" + func_decorator + "`\n\n"
|
|
|
|
# Add the 'args' and 'kwargs':
|
|
func_args = []
|
|
for name, param in inspect.signature(func).parameters.items():
|
|
default = param.default
|
|
if isinstance(default, str): default = f"\"{default}\""
|
|
if default == inspect.Parameter.empty: func_args.append(f"{name}")
|
|
else: func_args.append(f"{name}: {type(default).__name__} = {default}")
|
|
if len(func_args) > 0: func_args = f"{func_name} (\n\t" + "\n\t".join(func_args) + "\n):\n\n"
|
|
else: func_args = f"{func_name} ():\n\n"
|
|
|
|
# Get the params and return value part from the doc:
|
|
params_start = func_doc.find(":param")
|
|
return_start = func_doc.find(":return")
|
|
func_params = "\n" + func_doc[params_start:return_start] if params_start >= 0 else ""
|
|
func_return = "\n" + func_doc[return_start:] if return_start >= 0 else ""
|
|
|
|
# Isolate the documentation part:
|
|
if params_start >= 0: func_doc = func_doc[:params_start]
|
|
elif return_start >= 0: func_doc = func_doc[:return_start]
|
|
|
|
# Done here:
|
|
return func_head + func_args + func_doc + func_params + func_return
|
|
|
|
|
|
# ---------------------------------------------------------------------------------------------------------------------
|
|
|
|
|
|
def get_help(entity, skip_methods = None):
|
|
|
|
"""
|
|
Get the help documentation for anything from its docstring.
|
|
:param entity: The entity you want to get help for.
|
|
:param skip_methods: A list of methods to ignore if inspecting a class. Not valid for standalone functions.
|
|
:return: The help string.
|
|
"""
|
|
|
|
if inspect.isclass(entity): return get_help_for_class(entity, skip_methods = skip_methods)
|
|
else: return get_help_for_function(entity)
|
|
|
|
|
|
# *****************************************************************************************************************
|
|
# ***** ****
|
|
# *** MAIN PROGRAM ***
|
|
# ***** ****
|
|
# *****************************************************************************************************************
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
pass
|