docs: def _load_roles(self):
          """
          Load the roles, one per line, from the roles file.  This is
          called at startup and whenever the roles file changes.
  
          Note that it is not strictly an error for the roles file to
          be missing but a warning is logged in case that was not
          intended.
  
          Returns True if there was a change in roles, False otherwise.
          On any change, the config should be reapplied except this is
          typically skipped at startup as the first apply() will not
          yet have happened.
      """
          log = self._params.get('log', self._discard)
  
          new_role_set = None
          if self._roles_file:
              try:
                  with open(self._roles_file, 'r') as f:
                      new_role_set = set()
                      for line in f:
                          line = line.strip()
                          if line and not re.match(r'^\s*#', line):
                              new_role_set.add(line)
              except Exception as e:
                  log.warning("Open failed on roles file %r -- %s", self._roles_file, e)
          if self._role_set == new_role_set:
              log.info("Roles file check gave no changes from current set '%s'", self._fmt_set(new_role_set))
              return False
          elif self._role_set is None:
              log.info("Roles set to: %s", self._fmt_set(new_role_set))
          else:
              log.info("Roles changing from '%s' to '%s'", self._fmt_set(self._role_set), self._fmt_set(new_role_set))
          self._prev_role_set = self._role_set
          self._role_set = new_role_set
          return True