class_docstr: Evaluates coverage of code in the documentation.
class_docstr_tok: ["Evaluates","coverage","of","code","in","the","documentation","."]
code: def build_py_coverage(self) -> None:
      objects = self.env.domaindata["py"]["objects"]
      modules = self.env.domaindata["py"]["modules"]
  
      skip_undoc = self.config.coverage_skip_undoc_in_source
  
      for mod_name in modules:
          ignore = False
          for exp in self.mod_ignorexps:
              if exp.match(mod_name):
                  ignore = True
                  break
          if ignore or self.ignore_pyobj(mod_name):
              continue
  
          try:
              mod = import_module(mod_name)
          except ImportError as err:
              logger.warning(
                  __("module %s could not be imported: %s"),
                  mod_name,
                  err,
              )
              self.py_undoc[mod_name] = {"error": err}
              continue
  
          documented_objects: set[str] = set()
          undocumented_objects: set[str] = set()
  
          funcs = []
          classes: dict[str, list[str]] = {}
  
          for name, obj in inspect.getmembers(mod):
              # diverse module attributes are ignored:
              if name[0] == "_":
                  # begins in an underscore
                  continue
              if not hasattr(obj, "__module__"):
                  # cannot be attributed to a module
                  continue
              if obj.__module__ != mod_name:
                  # is not defined in this module
                  continue
  
              full_name = f"{mod_name}.{name}"
              if self.ignore_pyobj(full_name):
                  continue
  
              if inspect.isfunction(obj):
                  if full_name not in objects:
                      for exp in self.fun_ignorexps:
                          if exp.match(name):
                              break
                      else:
                          if skip_undoc and not obj.__doc__:
                              continue
                          funcs.append(name)
                          undocumented_objects.add(full_name)
                  else:
                      documented_objects.add(full_name)
              elif inspect.isclass(obj):
                  for exp in self.cls_ignorexps:
                      if exp.match(name):
                          break
                  else:
                      if full_name not in objects:
                          if skip_undoc and not obj.__doc__:
                              continue
                          # not documented at all
                          classes[name] = []
                          continue
  
                      attrs: list[str] = []
  
                      for attr_name in dir(obj):
                          if attr_name not in obj.__dict__:
                              continue
                          try:
                              attr = safe_getattr(obj, attr_name)
                          except AttributeError:
                              continue
                          if not (
                              inspect.ismethod(attr)
                              or inspect.isfunction(attr)
                          ):
                              continue
                          if attr_name[0] == "_":
                              # starts with an underscore, ignore it
                              continue
                          if skip_undoc and not attr.__doc__:
                              # skip methods without docstring if wished
                              continue
                          full_attr_name = f"{full_name}.{attr_name}"
                          if self.ignore_pyobj(full_attr_name):
                              continue
                          if full_attr_name not in objects:
                              attrs.append(attr_name)
                              undocumented_objects.add(full_attr_name)
                          else:
                              documented_objects.add(full_attr_name)
  
                      if attrs:
                          # some attributes are undocumented
                          classes[name] = attrs
  
          self.py_undoc[mod_name] = {"funcs": funcs, "classes": classes}
          self.py_undocumented[mod_name] = undocumented_objects
          self.py_documented[mod_name] = documented_objects
  
imports: from __future__ import annotations
  import glob
  import inspect
  import pickle
  import re
  import sys
  from importlib import import_module
  from os import path
  from typing import IO, TYPE_CHECKING, Any, TextIO
  import sphinx
  from sphinx.builders import Builder
  from sphinx.locale import __
  from sphinx.util import logging
  from sphinx.util.console import red
  from sphinx.util.inspect import safe_getattr
label_desc: Use image node_id 7 for calling the CoverageBuilder obj's underlying member method code with example usage: obj.build_py_coverage() without return types