コード例 #1
0
def parse_source(doc: Docstring, obj: Any):
    """Parses parameters' docstring to inspect type and description from source.

    Examples:
        >>> from mkapi.core.base import Base
        >>> doc = Docstring()
        >>> parse_source(doc, Base)
        >>> section = doc['Parameters']
        >>> section['name'].to_tuple()
        ('name', 'str, optional', 'Name of self.')
        >>> section = doc['Attributes']
        >>> section['html'].to_tuple()
        ('html', 'str', 'HTML output after conversion.')
    """
    signature = get_signature(obj)
    name = "Parameters"
    section = signature[name]
    if name in doc:
        section = section.merge(doc[name], force=True)
    if section:
        doc.set_section(section, replace=True)

    name = "Attributes"
    section = signature[name]
    if name not in doc and not section:
        return
    doc[name].update(section)
    if is_dataclass(obj) and "Parameters" in doc:
        for item in doc["Parameters"].items:
            if item.name in section:
                doc[name].set_item(item)
コード例 #2
0
ファイル: docstring.py プロジェクト: rhuygen/mkapi
def postprocess(doc: Docstring, obj: Any):
    parse_bases(doc, obj)
    if inspect.ismodule(obj) or inspect.isclass(obj):
        parse_attribute(doc, obj)
    if isinstance(obj, property):
        parse_property(doc, obj)

    if not callable(obj):
        return

    signature = get_signature(obj)
    if signature.signature is None:
        return

    def get_type(type: str) -> Type:
        if type.startswith("("):  # tuple
            type = type[1:-1]
        return Type(type)

    if doc["Parameters"] is not None:
        for item in doc["Parameters"].items:
            if not item.type and item.name in signature.parameters:
                item.type = get_type(signature.parameters[item.name])
            if "{default}" in item.desc.markdown and item.name in signature:
                default = signature.defaults[item.name]
                item.desc.markdown = item.desc.markdown.replace(
                    "{default}", default)

    if doc["Attributes"] is not None and signature.attributes:
        for item in doc["Attributes"].items:
            if not item.type and item.name in signature.attributes:
                item.type = get_type(signature.attributes[item.name])

    for name in ["Returns", "Yields"]:
        section = doc[name]
        if section is not None and not section.type:
            section.type = Type(getattr(signature, name.lower()))

    if doc["Returns"] is None and doc["Yields"] is None:
        from mkapi.core.node import get_kind

        kind = get_kind(obj)
        if kind == "generator":
            doc.type = Type(signature.yields)
        else:
            doc.type = Type(signature.returns)

    for section in doc.sections:
        if section.name in ["Example", "Examples"]:
            break
        if section.markdown:
            section.markdown = replace_link(obj, section.markdown)
        else:
            for item in section.items:
                if item.markdown:
                    item.markdown = replace_link(obj, item.markdown)
コード例 #3
0
def parse_bases(doc: Docstring, obj: Any):
    """Parses base classes to create a Base(s) line."""
    if not inspect.isclass(obj) or not hasattr(obj, "mro"):
        return
    objs = get_mro(obj)[1:]
    if not objs:
        return
    types = [get_link(obj, include_module=True) for obj in objs]
    items = [Item(type=Type(type)) for type in types if type]
    doc.set_section(Section("Bases", items=items))
コード例 #4
0
ファイル: docstring.py プロジェクト: rhuygen/mkapi
def parse_property(doc: Docstring, obj: Any):
    """Parses property's docstring to inspect type."""
    doc.type = Type(get_signature(obj.fget).returns)
    if not doc.type:
        section = doc.sections[0]
        markdown = section.markdown
        type, markdown = preprocess.split_type(markdown)
        if type:
            doc.type = Type(type)
            section.markdown = markdown
コード例 #5
0
def get_docstring(obj: Any) -> Docstring:
    """Returns a [Docstring]() instance."""
    doc = inspect.getdoc(obj)
    if doc:
        sections = []
        for section in split_section(doc):
            sections.append(get_section(*section))
        docstring = Docstring(sections)
    else:
        return Docstring()
    postprocess(docstring, obj)
    return docstring
コード例 #6
0
def postprocess(doc: Docstring, obj: Any):
    parse_bases(doc, obj)
    parse_source(doc, obj)
    if not callable(obj):
        return

    signature = get_signature(obj)
    if signature.signature is None:
        return

    if "Parameters" in doc:
        for item in doc["Parameters"].items:
            description = item.description
            if "{default}" in description.name and item.name in signature:
                default = signature.defaults[item.name]
                description.markdown = description.name.replace(
                    "{default}", default)

    for name in ["Returns", "Yields"]:
        if name in doc:
            section = doc[name]
            if not section.type:
                section.type = Type(getattr(signature, name.lower()))

    if "Returns" not in doc and "Yields" not in doc:
        from mkapi.core.node import get_kind

        kind = get_kind(obj)
        if kind == "generator":
            doc.type = Type(signature.yields)
        else:
            doc.type = Type(signature.returns)

    sections: List[Section] = []
    for section in doc.sections:
        if section.name not in ["Example", "Examples"]:
            for base in section:
                base.markdown = replace_link(obj, base.markdown)
        if section.name in ["Note", "Notes", "Warning", "Warnings"]:
            markdown = preprocess.admonition(section.name, section.markdown)
            if sections and sections[-1].name == "":
                sections[-1].markdown += "\n\n" + markdown
                continue
            else:
                section.name = ""
                section.markdown = markdown
        sections.append(section)
    doc.sections = sections
コード例 #7
0
ファイル: docstring.py プロジェクト: rhuygen/mkapi
def get_docstring(obj: Any) -> Docstring:
    """Returns a [Docstring]() instance."""
    doc = inspect.getdoc(obj)
    if doc:
        sections = []
        for section in split_section(doc):
            sections.append(get_section(*section))
        docstring = Docstring(sections)
    elif inspect.isclass(obj) and hasattr(obj, "mro"):
        bases = obj.mro()[1:-1]
        if not bases:
            return Docstring()
        docstring = Docstring([Section()])
    else:
        return Docstring()
    postprocess(docstring, obj)
    return docstring
コード例 #8
0
def test_docstring_copy():
    d = Docstring()
    a = Section("Parameters")
    d.set_section(a)
    assert "Parameters" in d
    assert d["Parameters"] is a
    a = Section("Arguments")
    d.set_section(a, copy=True)
    assert "Arguments" in d
    assert d["Arguments"] is not a