code: def test_source(self):
      source = (
          f"File: {getsourcefile(_helper_test_source)}"
          f"\n\n{getsource(_helper_test_source)}"
      )
      with patch.dict(self.dispatcher.funcs, {}):
          self.dispatcher.add(
              signature=(int,), func=_helper_test_source
          )
          self.assertEqual(self.dispatcher._source(0), source)
          with redirect_stdout(StringIO()) as buffer:
              self.dispatcher.source(0)
  
          # buffer.getvalue() has two newlines at the end, one due to `print`
          self.assertEqual(buffer.getvalue()[:-1], source)
          with self.assertRaisesRegex(TypeError, "No function found"):
              self.dispatcher._source(0.5)
  
file_path: botorch/test/utils/test_dispatcher.py
imports: from __future__ import annotations
  from contextlib import redirect_stdout
  from inspect import getsource, getsourcefile
  from io import StringIO
  from itertools import product
  from unittest.mock import patch
  from botorch.utils.dispatcher import Dispatcher, MDNotImplementedError
  from botorch.utils.testing import BotorchTestCase
label_desc: Use image node_id 9 for calling the TestDispatcher obj's underlying member method code with example usage: obj.test_source() without return types