code: def test_trials_dataframe_with_multi_objective_optimization_with_fail_and_pruned(
      attrs: tuple[str, ...], multi_index: bool
  ) -> None:
      study = create_study(directions=["minimize", "maximize"])
      study.add_trial(create_trial(state=TrialState.FAIL))
      study.add_trial(create_trial(state=TrialState.PRUNED))
      df = study.trials_dataframe(attrs=attrs, multi_index=multi_index)
  
      # without set_metric_names()
      if multi_index:
          for i in range(2):
              assert df.get("values")[0][i] is None
              assert df.get("values")[1][i] is None
      else:
          for i in range(2):
              assert df.values_0[i] is None
              assert df.values_1[i] is None
  
      # with set_metric_names()
      study.set_metric_names(["v0", "v1"])
      df = study.trials_dataframe(attrs=attrs, multi_index=multi_index)
      if multi_index:
          assert df.get("values")["v0"][0] is None
          assert df.get("values")["v1"][0] is None
      else:
          assert df.get("values_v0")[0] is None
          assert df.get("values_v1")[0] is None
  
file_path: optuna/tests/study_tests/test_dataframe.py
imports: from __future__ import annotations
  import pandas
  import pytest
  from optuna import create_study
  from optuna import create_trial
  from optuna import Trial
  from optuna.testing.storages import STORAGE_MODES
  from optuna.testing.storages import StorageSupplier
  from optuna.trial import TrialState
label_desc: Use image node_id 5 for calling a global function with example usage: test_trials_dataframe_with_multi_objective_optimization_with_fail_and_pruned(attrs, multi_index) without return types