class_docstr: The state of a dataset.
code: def __post_init__(self) -> None:
      with StepProfiler(
          method="DatasetState.__post_init__",
          step="get_dataset_level_artifact_states",
          context=f"dataset={self.dataset}",
      ):
          self.artifact_state_by_step = {
              processing_step.name: ArtifactState(
                  processing_step=processing_step,
                  dataset=self.dataset,
                  revision=self.revision,
                  config=None,
                  split=None,
                  pending_jobs_df=self.pending_jobs_df[
                      (
                          self.pending_jobs_df["revision"]
                          == self.revision
                      )
                      & (self.pending_jobs_df["config"].isnull())
                      & (self.pending_jobs_df["split"].isnull())
                      & (
                          self.pending_jobs_df["type"]
                          == processing_step.job_type
                      )
                  ],
                  cache_entries_df=self.cache_entries_df[
                      (
                          self.cache_entries_df["kind"]
                          == processing_step.cache_kind
                      )
                      & (self.cache_entries_df["config"].isnull())
                      & (self.cache_entries_df["split"].isnull())
                  ],
              )
              for processing_step in self.processing_graph.get_input_type_processing_steps(
                  input_type="dataset"
              )
          }
  
          with StepProfiler(
              method="DatasetState.__post_init__",
              step="get_config_names",
              context=f"dataset={self.dataset}",
          ):
              self.config_names = fetch_names(
                  dataset=self.dataset,
                  config=None,
                  cache_kinds=DATASET_CONFIG_NAMES_KINDS,
                  names_field="config_names",
                  name_field="config",
              )  # Note that we use the cached content even the revision is different (ie. maybe obsolete)
  
          with StepProfiler(
              method="DatasetState.__post_init__",
              step="get_config_states",
              context=f"dataset={self.dataset}",
          ):
              self.config_states = [
                  ConfigState(
                      dataset=self.dataset,
                      revision=self.revision,
                      config=config_name,
                      processing_graph=self.processing_graph,
                      pending_jobs_df=self.pending_jobs_df[
                          (
                              self.pending_jobs_df["revision"]
                              == self.revision
                          )
                          & (
                              self.pending_jobs_df["config"]
                              == config_name
                          )
                      ],
                      cache_entries_df=self.cache_entries_df[
                          self.cache_entries_df["config"] == config_name
                      ],
                  )
                  for config_name in self.config_names
              ]
  
imports: import logging
  from dataclasses import dataclass, field
  from typing import Optional
  import pandas
  from libcommon.constants import CONFIG_SPLIT_NAMES_KINDS, DATASET_CONFIG_NAMES_KINDS, ERROR_CODES_TO_RETRY, MAX_FAILED_RUNS
  from libcommon.processing_graph import Artifact, ProcessingGraph
  from libcommon.prometheus import StepProfiler
  from libcommon.simple_cache import CacheEntryMetadata, fetch_names
label_desc: Use image node_id 1 for calling the DatasetState obj's underlying member method code with example usage: obj.__post_init__() without return types