code: def test_complex_defaults(self):
      ### test that demod gets created first and then is used to create demo instead of the None default
      experiment = {
          "demo": {
              "_name": "DemoComplexDefaults",
              "strval": "foo",
              "obj": "$obj",
          },
          "obj": {
              "_name": "DemoDefaults",
              "strval": "bar",
              "intval1": 20,
          },
      }
      e = ExperimentConfig(experiment)
  
      self.assertTrue(isinstance(e["demo"], DemoComplexDefaults))
      self.assertTrue(isinstance(e["obj"], DemoDefaults))
  
      self.assertEqual(e["obj"].strval, "bar")
      self.assertEqual(e["obj"].intval1, 20)
      self.assertEqual(e["obj"].intval2, None)
  
      self.assertEqual(e["demo"].simple, "foo")
      self.assertEqual(e["demo"].complex.strval, "bar")
      self.assertEqual(e["demo"].complex.intval1, 20)
      self.assertEqual(e["demo"].complex.intval2, None)
  
imports: import unittest
  from pathlib import Path
  from typing import Any, Dict, List
  from transfer_nlp.plugins.config import CallableInstantiationError, ExperimentConfig, LoopInConfigError, UnknownPluginException, UnknownReferenceError, register_plugin
label_desc: Use image node_id 13 for calling the RegistryTest obj's underlying member method code with example usage: obj.test_complex_defaults() without return types