def _field_names(self) -> Set[Text]:
    """Returns this config's field names as a set."""
    if dataclasses.is_dataclass(self):
      # Dataclasses have their own way of storing information about their
      # fields, so use that.
      field_names = {field.name for field in dataclasses.fields(self)}
    else:
      field_names = set(vars(self))
      field_names.update(name for name, _ in (
          inspect.getmembers(type(self), lambda m: isinstance(m, property))))

    return {
        field_name for field_name in field_names
        if not field_name.startswith("_")  # Skip private fields.
    }
Returns this config's field names as a set.
language/canine/config_utils.py