class_docstr: TestCallback
code: def test_callbackslist(self) -> None:
      callbacklist = CallbackList(
          [TestCallback.CustomCallback(), TestCallback.CustomCallback()]
      )
  
      cb = TestCallback.CustomCallback()
      callbacklist.add_callback(cb)
      print(callbacklist)
      self.assertEqual(len(callbacklist), 2)
      callbacklist.pop_callback(cb)
      self.assertEqual(len(callbacklist), 1)
  
      train_log = self._init_log()
      eval_log = self._init_log()
  
      train_epoch_nums = 3
      train_batch_nums = 5
      # simulate the train loop.
      callbacklist.on_train_begin(train_log)
      for train_epoch in range(train_epoch_nums):
          callbacklist.on_epoch_begin(train_epoch, train_log)
          for _ in range(train_batch_nums):
              mock_batch = (None, None)
              callbacklist.on_train_batch_begin(mock_batch, train_log)
              callbacklist.on_train_batch_end(mock_batch, train_log)
          callbacklist.on_epoch_end(train_epoch, train_log)
      callbacklist.on_train_end(train_log)
  
      def _assert_train_attrs(attr, gt):
          self.assertEqual(train_log[attr], gt)
  
      num_callbacks = len(callbacklist)
      _assert_train_attrs("on_batch_begin", 0 * num_callbacks)
      _assert_train_attrs("on_batch_end", 0 * num_callbacks)
      _assert_train_attrs(
          "on_epoch_begin", train_epoch_nums * num_callbacks
      )
      _assert_train_attrs(
          "on_epoch_end", train_epoch_nums * num_callbacks
      )
      _assert_train_attrs(
          "on_train_batch_begin",
          train_epoch_nums * train_batch_nums * num_callbacks,
      )
      _assert_train_attrs(
          "on_train_batch_end",
          train_epoch_nums * train_batch_nums * num_callbacks,
      )
      _assert_train_attrs("on_train_begin", 1 * num_callbacks)
      _assert_train_attrs("on_train_end", 1 * num_callbacks)
  
      # simulate the eval loop.
      eval_epoch_nums = 5
      eval_batch_nums = 10
      callbacklist.on_eval_begin(eval_log)
      for eval_epoch in range(eval_epoch_nums):
          callbacklist.on_epoch_begin(eval_epoch, eval_log)
          for _ in range(eval_batch_nums):
              mock_batch = (None, None)
              callbacklist.on_eval_batch_begin(mock_batch, eval_log)
              callbacklist.on_eval_batch_end(mock_batch, eval_log)
          callbacklist.on_epoch_end(eval_epoch, eval_log)
      callbacklist.on_eval_end(eval_log)
  
      def _assert_eval_attrs(attr, gt):
          self.assertEqual(eval_log[attr], gt)
  
      _assert_eval_attrs("on_batch_begin", 0 * num_callbacks)
      _assert_eval_attrs("on_batch_end", 0 * num_callbacks)
      _assert_eval_attrs(
          "on_epoch_begin", eval_epoch_nums * num_callbacks
      )
      _assert_eval_attrs(
          "on_epoch_end", eval_epoch_nums * num_callbacks
      )
      _assert_eval_attrs(
          "on_eval_batch_begin",
          eval_epoch_nums * eval_batch_nums * num_callbacks,
      )
      _assert_eval_attrs(
          "on_eval_batch_end",
          eval_epoch_nums * eval_batch_nums * num_callbacks,
      )
      _assert_eval_attrs("on_eval_begin", 1 * num_callbacks)
      _assert_eval_attrs("on_eval_end", 1 * num_callbacks)
  
file_path: towhee/tests/unittests/trainer/test_callback.py
imports: import unittest
  from typing import Dict, Tuple
  from tqdm import tqdm
  from towhee.trainer.callback import TrainerControl, Callback, CallbackList, EarlyStoppingCallback, ModelCheckpointCallback, TensorBoardCallBack, PrintCallBack, ProgressBarCallBack
label_desc: Use image node_id 3 for calling the TestCallback obj's underlying member method code with example usage: obj.test_callbackslist() without return types