class_docstr: Evaluates coverage of code in the documentation.
code: def build_py_coverage(self) -> None:
      objects = self.env.domaindata["py"]["objects"]  # type: ignore
  
      # objects are sometimes not referenced in the docs as they are
      # in the source.  Here we simply grab the method and class of
      # the object
      abbr_names = set()
      for obj_name in objects:
          # only include method and class
          abbr_names.add(method_from_obj(obj_name))
  
      modules = self.env.domaindata["py"]["modules"]  # type: ignore
      for mod_name in self.add_modules:
          modules[mod_name] = None
  
      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
  
          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)
              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:
                              # it's possible object is abbreviated
                              abbr_name = method_from_obj(obj_name)
                              if abbr_name not in abbr_names:
                                  attrs.append(attr_name)
                      if attrs:
                          # some attributes are undocumented
                          classes[name] = attrs
  
          self.py_undoc[mod_name] = {"funcs": funcs, "classes": classes}
  
imports: import glob
  from importlib import import_module
  import inspect
  from os import path
  import pickle
  import re
  from typing import IO, Any, Dict, List, Pattern, Set, Tuple
  import sphinx
  from sphinx.application 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