def test_get_section(name, mode): def func(): pass section = get_section(Node(func), name, mode) section.name == name assert not section
def inherit_signature(node: Node, name: str = ""): """Inherits Parameters or Attributes section from signature. Args: node: Node instance. name: Section name: 'Parameters' or 'Attributes', or ''. If name is '', both sections are inherited. Examples: >>> from mkapi.core.object import get_object >>> base = Node(get_object('mkapi.core.base.Base')) >>> [item.name for item in base.docstring['Attributes'].items] ['html'] >>> inherit_signature(base) >>> [item.name for item in base.docstring['Attributes'].items] ['name', 'markdown', 'html'] """ if not name: for name in ["Parameters", "Attributes"]: inherit_signature(node, name) return _, params = get_params(node, name) if not params: return node_section = node.docstring[name] items = [] for item_name, type in params.items(): if node_section is None or item_name not in node_section: item = Item(item_name, markdown="", type=Type(type)) else: item = node_section[item_name] # type:ignore items.append(item) node.docstring[name] = Section(name, items=items)
def transform_property(node: Node): section = node.docstring["Attributes"] members = [] for member in node.members: if "property" in member.object.kind: if section is None: section = Section("Attributes") node.docstring['Attributes'] = section name = member.object.name kind = member.object.kind type = member.object.type markdown = member.docstring.sections[0].markdown item = Item(name, markdown, type=type, kind=kind) section.items.append(item) else: members.append(member) node.members = members
def transform(node: Node, filters: Optional[List[str]] = None): if node.object.kind.replace("abstract ", "") in ["class", "dataclass"]: transform_class(node, filters) elif node.object.kind in ["module", "package"]: transform_module(node, filters) for x in node.walk(): sort(x) for member in node.members: transform(member, filters)
def test_link_from_toc(): from examples.google_style import ExampleClass node = Node(ExampleClass) assert len(node.docstring.sections) == 4 P.transform(node) assert len(node.docstring.sections) == 5 assert "Methods" in node.docstring section = node.docstring['Methods'] html = section.items[0].html assert '<a href="#examples.google_style.ExampleClass.message">' in html
def transform(node: Node, filters: Optional[List[str]] = None): if node.docstring is None: return if node.object.kind in ["class", "dataclass"]: transform_class(node, filters) elif node.object.kind in ["module", "package"]: transform_module(node, filters) for x in node.walk(): sort(x) for member in node.members: transform(member, filters)
def test_transform_module(module): node = Node(module) P.transform(node, ["link"]) q = module.__name__ section = node.docstring["Functions"] assert "add" in section item = section["add"] item.markdown.startswith("Returns") item.html.startswith(f'<a href="#{q}.add">add</a>') assert "gen" in section section = node.docstring["Classes"] assert "ExampleClass" in section assert "ExampleDataClass" in section
def test_transform_class(node): P.transform(node) section = node.docstring["Methods"] q = A.__qualname__ for name in "fgab": assert name in section item = section[name] item.markdown = name * 3 item.html.startswith(f'<a href="#{q}.{name}">{name}</a>') section = node.docstring["Classes"] assert "B" in section item = section["B"].markdown == "BBB" node = Node(A.B) P.transform_class(node)
def transform_property(node: Node, filters: List[str] = None): section = None members = [] for member in node.members: object = member.object if "property" in object.kind: if section is None: section = node.docstring["Attributes"] name = object.name kind = object.kind type = object.type description = member.docstring.sections[0].markdown item = Item(name, type, Inline(description), kind=kind) if filters and "sourcelink" in filters: source_link_from_section_item(item, object) section.items.append(item) else: members.append(member) node.members = members
def inherit_base(node: Node, base: Node, name: str = ""): """Inherits Parameters or Attributes section from base class. Args: node: Node instance. base: Node instance of a super class. name: Section name: 'Parameters' or 'Attributes', or ''. If name is '', both sections are inherited. Examples: >>> from mkapi.core.object import get_object >>> base = Node(get_object('mkapi.core.base.Base')) >>> node = Node(get_object('mkapi.core.base.Type')) >>> [item.name for item in base.docstring['Parameters'].items] ['name', 'markdown'] >>> node.docstring['Parameters'] is None True >>> inherit_base(node, base) >>> [item.name for item in node.docstring['Parameters'].items] ['name', 'markdown'] """ if not name: for name in ["Parameters", "Attributes"]: inherit_base(node, base, name) return base_section = base.docstring[name] if base_section is None: return _, node_params = get_params(node, name) _, base_params = get_params(base, name) node_section = node.docstring[name] items = [] for item in base_section.items: if node_section is None or item.name not in node_section: if (item.name in node_params and node_params[item.name] == base_params[item.name]): items.append(item) if node_section is not None: for item in node_section.items: if item not in items: items.append(item) node.docstring[name] = Section(name, items=items) # type:ignore
def transform_members(node: Node, mode: str, filters: Optional[List[str]] = None): def is_member(kind): if mode in ["method", "function"]: return mode in kind or kind == "generator" else: return mode in kind and 'method' not in kind members = [ member for member in node.members if is_member(member.object.kind) ] if not members: return name = mode[0].upper() + mode[1:] + ("es" if mode == "class" else "s") section = Section(name) for member in members: object = member.object kind = object.kind type = get_type(member) section_ = member.docstring[""] if section_: markdown = section_.markdown if "\n\n" in markdown: markdown = markdown.split("\n\n")[0] item = Item(name, markdown, type=type, kind=kind) item.markdown, url, signature = "", "", "" if filters and "link" in filters: url = "#" + object.id if object.kind not in ["class", "dataclass"]: signature = "(" + ",".join( object.signature.parameters.keys()) + ")" item.html = renderer.render_object_member(object.name, url, signature) section.items.append(item) node.docstring[name] = section
def transform_module(node: Node, filters: Optional[List[str]] = None): transform_members(node, "class", filters) transform_members(node, "function", filters) if not filters or "all" not in filters: node.members = []
def node(): node = Node(A) return node
def test_is_complete(): assert is_complete(Node(Base)) assert not is_complete(Node(Inline))
def transform_module(node: Node, filters: List[str]): transform_members(node, "class", filters) transform_members(node, "function", filters) node.members = []