code: def _check_recursive_df_equality(self, o_1, o_2):
      assert type(o_1) is type(o_2)
  
      if isinstance(o_1, list):
          assert len(o_1) == len(o_2)
          for item_1, item_2 in zip(o_1, o_2):
              self._check_recursive_df_equality(item_1, item_2)
      elif isinstance(o_1, dict):
          assert o_1.keys() == o_2.keys()
          for key, item_1 in o_1.items():
              item_2 = o_2[key]
              self._check_recursive_df_equality(item_1, item_2)
      elif isinstance(o_1, pd.DataFrame):
          assert o_1.equals(o_2)
      else:
          assert o_1 == o_2
  
file_path: responsible-ai-toolbox/responsibleai/tests/causal/test_causal_result_versioning.py
imports: import json
  import pandas
  import pytest
  from jsonschema import ValidationError
  from raiutils.models import ModelTask
  from responsibleai._tools.causal.causal_result import CausalResult
  from responsibleai._tools.shared.versions import CausalVersions
  from responsibleai.managers.causal_manager import CausalManager
label_desc: Use image node_id 2 for calling the TestCausalVersioning obj's underlying member method code with example usage: obj._check_recursive_df_equality(o_1, o_2) without return types