Esempio n. 1
0
    def get_attribute_documentation(
            node: ObjectNode,
            attribute_data: Optional[dict] = None) -> Attribute:
        """
        Get the documentation for an attribute.

        Arguments:
            node: The node representing the method and its parents.
            attribute_data: Docstring and annotation for this attribute.

        Returns:
            The documented attribute object.
        """
        if attribute_data is None:
            if node.parent_is_class():
                attribute_data = get_class_attributes(node.parent.obj).get(
                    node.name, {})  # type: ignore
            else:
                attribute_data = get_module_attributes(node.root.obj).get(
                    node.name, {})
        return Attribute(
            name=node.name,
            path=node.dotted_path,
            file_path=node.file_path,
            docstring=attribute_data.get("docstring", ""),
            attr_type=attribute_data.get("annotation", None),
        )
Esempio n. 2
0
    def get_annotated_dataclass_field(
            node: ObjectNode,
            attribute_data: Optional[dict] = None) -> Attribute:
        """
        Get the documentation for a dataclass field.

        Arguments:
            node: The node representing the annotation and its parents.
            attribute_data: Docstring and annotation for this attribute.

        Returns:
            The documented attribute object.
        """
        if attribute_data is None:
            if node.parent_is_class():
                attribute_data = get_class_attributes(node.parent.obj).get(
                    node.name, {})  # type: ignore
            else:
                attribute_data = get_module_attributes(node.root.obj).get(
                    node.name, {})

        return Attribute(
            name=node.name,
            path=node.dotted_path,
            file_path=node.file_path,
            docstring=attribute_data["docstring"],
            attr_type=attribute_data["annotation"],
            properties=["dataclass-field"],
        )
Esempio n. 3
0
    def get_module_documentation(self,
                                 node: ObjectNode,
                                 select_members=None) -> Module:
        """
        Get the documentation for a module and its children.

        Arguments:
            node: The node representing the module and its parents.
            select_members: Explicit members to select.

        Returns:
            The documented module object.
        """
        module = node.obj
        path = node.dotted_path
        name = path.split(".")[-1]
        source: Optional[Source]

        try:
            source = Source(inspect.getsource(module), 1)
        except OSError as error:
            try:
                code = Path(node.file_path).read_text()
            except (OSError, UnicodeDecodeError):
                self.errors.append(
                    f"Couldn't read source for '{path}': {error}")
                source = None
            else:
                source = Source(code, 1) if code else None

        root_object = Module(
            name=name,
            path=path,
            file_path=node.file_path,
            docstring=inspect.getdoc(module),
            source=source,
        )

        if select_members is False:
            return root_object

        select_members = select_members or set()

        attributes_data = get_module_attributes(module)
        root_object.parse_docstring(self.docstring_parser,
                                    attributes=attributes_data)

        for member_name, member in inspect.getmembers(module):
            if self.select(member_name, select_members):  # type: ignore
                child_node = ObjectNode(member, member_name, parent=node)
                if child_node.is_class(
                ) and node.root.obj is inspect.getmodule(member):
                    root_object.add_child(
                        self.get_class_documentation(child_node))
                elif child_node.is_function(
                ) and node.root.obj is inspect.getmodule(member):
                    root_object.add_child(
                        self.get_function_documentation(child_node))
                elif member_name in attributes_data:
                    root_object.add_child(
                        self.get_attribute_documentation(
                            child_node, attributes_data[member_name]))

        if hasattr(module, "__path__"):  # noqa: WPS421 (hasattr)
            for _, modname, _ in pkgutil.iter_modules(module.__path__):
                if self.select(modname, select_members):
                    leaf = get_object_tree(f"{path}.{modname}")
                    root_object.add_child(self.get_module_documentation(leaf))

        return root_object
Esempio n. 4
0
 def setup(self):
     """Setup reusable attributes."""
     self.attributes = get_module_attributes(attr_module)