code: def _eval_epoch(fn, trainer, model, batches, key, device):
      return [
          {
              "name": f"Callback.on_{fn}_epoch_start",
              "args": (trainer, model),
          },
          {"name": f"on_{fn}_epoch_start"},
          *HookedModel._eval_batch(
              fn, trainer, model, batches, key, device=device
          ),
          {
              "name": f"Callback.on_{fn}_epoch_end",
              "args": (trainer, model),
          },
          {"name": f"on_{fn}_epoch_end"},
      ]
  
imports: from functools import partial, update_wrapper
  from inspect import getmembers, isfunction
  from unittest import mock
  from unittest.mock import ANY, PropertyMock
  import pytest
  import torch
  from lightning.fabric.utilities.imports import _TORCH_GREATER_EQUAL_2_0
  from lightning.pytorch import Callback, LightningDataModule, LightningModule, Trainer, __version__
  from lightning.pytorch.demos.boring_classes import BoringDataModule, BoringModel, RandomDataset
  from lightning.pytorch.utilities.model_helpers import is_overridden
  from torch import Tensor
  from torch.utils.data import DataLoader
  from tests_pytorch.helpers.runif import RunIf
label_desc: Use image node_id 5 for calling the HookedModel obj's underlying member method code with example usage: obj._eval_epoch(fn, trainer, model, batches, key, device) and returns: list