Source code for command_tree.doc_string_parser


import re
from abc import ABCMeta, abstractmethod

[docs]class DocStringInfo(object): """Structured info about the object's docstring. Args: description (str): the object description, typically the first line of the docstring """
[docs] class Argument(object): """Structured info about one argument. Args: name (str): the name of the argument help (str): the description of the argument """ def __init__(self, name, help = None): self.name = name self.help = help
def __init__(self, description = None): self.description = description self.argument_infos = {}
[docs] def add_argument_info(self, arginfo): """Add an argument info instance. Args: arginfo (DocStringInfo.Argument): the info instance """ self.argument_infos[arginfo.name] = arginfo
[docs]class ParserBase(object): """Base class to define interface for the doc string parser classes""" __metaclass__ = ABCMeta
[docs] @abstractmethod def parse(self, content): """Parse the docstring content. Args: content (str): the whole docstring content Returns: DocStringInfo: structured info """
[docs]class GoogleParser(ParserBase): """Parser class for Google style doc string comment format. See: https://google.github.io/styleguide/pyguide.html#Comments """ _doc_arg_pattern = re.compile("([a-zA-Z0-9_]{1,}) ?([()_.a-zA-Z09]{1,})?: (.+)")
[docs] def parse(self, content): """See: :py:func:`command_tree.doc_string_parser.ParserBase.parse`.""" info = DocStringInfo() parts = content.split("Args:") desc = parts[0].strip() if len(desc): info.description = desc if len(parts) > 1: arguments_definitions = parts[1].strip() for line in arguments_definitions.split("\n"): matches = self._doc_arg_pattern.match(line.strip()) if not matches: continue name, arg_type, arg_help = matches.groups() info.add_argument_info(DocStringInfo.Argument(name, arg_help.strip())) return info