# Buggy code
def _reset_eval_dataloader(
    self, model: LightningModule, mode: str
) -> Tuple[List[Union[int, float]], List[DataLoader]]:
    """Generic method to reset a dataloader for evaluation.

    Args:
        model: The current `LightningModule`
        mode: Either `'val'` or `'test'`

    Returns:
        Tuple (num_batches, dataloaders)
    """
    # always get the loaders first so we can count how many there are
    loader_name = f"{mode}_dataloader"
    dataloaders = self.request_dataloader(getattr(model, loader_name))

    # when overfitting use the training loader as val and test
    # duplicate it the numb of times needed to match the train loaders
    if self.overfit_batches > 0:
        num_loaders = len(dataloaders)
        train_dataloader = self.request_dataloader(getattr(model, "train_dataloader"))
        dataloaders = [deepcopy(train_dataloader) for _ in range(num_loaders)]

    if not isinstance(dataloaders, list):
        dataloaders = [dataloaders]

    self.dev_debugger.track_load_dataloader_call(loader_name, dataloaders=dataloaders)

    for loader_i in range(len(dataloaders)):
        loader = dataloaders[loader_i]

        # shuffling in val and test set is bad practice
        if (
            mode in ("val", "test")
            and hasattr(loader, "sampler")
            and isinstance(loader.sampler, RandomSampler)
        ):
            # when overfitting, the dataloader should not have sampler
            if self.overfit_batches > 0:
                rank_zero_warn(
                    "You requested to overfit but enabled test/val dataloader shuffling."
                    " We are turning it off for you."
                )
                dataloaders[loader_i] = self.replace_sampler(
                    loader, SequentialSampler(loader.dataset)
                )

            else:
                rank_zero_warn(
                    f"Your {mode}_dataloader has `shuffle=True`, it is best practice to turn"
                    " this off for validation and test dataloaders."
                )

    if any([dl is None for dl in dataloaders]):
        rank_zero_warn("One of given dataloaders is None and it will be skipped.")

    # add samplers
    dataloaders = [
        self.auto_add_sampler(dl, train=False) for dl in dataloaders if dl is not None
    ]

    loader_num_batches = []

    # determine number of batches
    # datasets could be none, 1 or 2+
    if len(dataloaders) != 0:
        for i, dataloader in enumerate(dataloaders):
            num_batches = len(dataloader) if has_len(dataloader) else float("inf")
            self._worker_check(dataloader, f"{mode} dataloader {i}")

            # percent or num_steps
            limit_eval_batches = getattr(self, f"limit_{mode}_batches")

            # limit num batches either as a percent or num steps
            if isinstance(limit_eval_batches, int) or limit_eval_batches == 0.0:
                num_batches = min(num_batches, int(limit_eval_batches))
            elif num_batches != float("inf"):
                num_batches = int(num_batches * limit_eval_batches)
            elif limit_eval_batches != 1.0:
                raise MisconfigurationException(
                    "When using an IterableDataset for `limit_{mode}_batches`,"
                    f" `Trainer(limit_{mode}_batches)` must be `0.0`, `1.0` or an int. An int k specifies"
                    f" `num_{mode}_batches` to use."
                )

            if (
                num_batches == 0
                and limit_eval_batches > 0.0
                and isinstance(limit_eval_batches, float)
            ):
                min_pct = 1.0 / len(dataloader)
                raise MisconfigurationException(
                    f"you requested to check {limit_eval_batches} of the {mode} dataloader but"
                    f" {limit_eval_batches}*{num_batches} < 1. Please increase the limit_{mode}_batches."
                    f" Try at least limit_{mode}_batches={min_pct}"
                )

            loader_num_batches.append(num_batches)

    return loader_num_batches, dataloaders


# Traceback (TypeError)

Traceback (most recent call last):
  File "stl/lightning/callbacks/tests/test_model_checkpoint.py", line 371, in test_ckpt_metric_names
    trainer.fit(model)
  File "pytorch_lightning/trainer/trainer.py", line 487, in fit
    results = self.accelerator_backend.train()
  File "pytorch_lightning/accelerators/cpu_backend.py", line 47, in train
    results = self.train_or_test()
  File "pytorch_lightning/accelerators/base_backend.py", line 47, in train_or_test
    results = self.trainer.train()
  File "pytorch_lightning/trainer/trainer.py", line 509, in train
    self.run_sanity_check(self.get_model())
  File "pytorch_lightning/trainer/trainer.py", line 699, in run_sanity_check
    _, eval_results = self.run_evaluation(test_mode=False, max_batches=self.num_sanity_val_batches)
  File "pytorch_lightning/trainer/trainer.py", line 619, in run_evaluation
    output = self.evaluation_loop.evaluation_step(test_mode, batch, batch_idx, dataloader_idx)
  File "pytorch_lightning/trainer/evaluation_loop.py", line 163, in evaluation_step
    output = self.trainer.accelerator_backend.validation_step(args)
  File "pytorch_lightning/accelerators/cpu_backend.py", line 63, in validation_step
    output = self.trainer.model.validation_step(*args)
TypeError: validation_step() takes 3 positional arguments but 4 were given

# Fixed code
def _reset_eval_dataloader(
    self, model: LightningModule, mode: str
) -> Tuple[List[Union[int, float]], List[DataLoader]]:
    """Generic method to reset a dataloader for evaluation.

    Args:
        model: The current `LightningModule`
        mode: Either `'val'` or `'test'`

    Returns:
        Tuple (num_batches, dataloaders)
    """
    # always get the loaders first so we can count how many there are
    loader_name = f"{mode}_dataloader"
    dataloaders = self.request_dataloader(getattr(model, loader_name))

    if not isinstance(dataloaders, list):
        dataloaders = [dataloaders]

    # when overfitting use the training loader as val and test
    # duplicate it the numb of times needed to match the train loaders
    if self.overfit_batches > 0:
        num_loaders = len(dataloaders)
        train_dataloader = self.request_dataloader(getattr(model, "train_dataloader"))
        dataloaders = [deepcopy(train_dataloader) for _ in range(num_loaders)]

    self.dev_debugger.track_load_dataloader_call(loader_name, dataloaders=dataloaders)

    for loader_i in range(len(dataloaders)):
        loader = dataloaders[loader_i]

        # shuffling in val and test set is bad practice
        if (
            mode in ("val", "test")
            and hasattr(loader, "sampler")
            and isinstance(loader.sampler, RandomSampler)
        ):
            # when overfitting, the dataloader should not have sampler
            if self.overfit_batches > 0:
                rank_zero_warn(
                    "You requested to overfit but enabled test/val dataloader shuffling."
                    " We are turning it off for you."
                )
                dataloaders[loader_i] = self.replace_sampler(
                    loader, SequentialSampler(loader.dataset)
                )

            else:
                rank_zero_warn(
                    f"Your {mode}_dataloader has `shuffle=True`, it is best practice to turn"
                    " this off for validation and test dataloaders."
                )

    if any([dl is None for dl in dataloaders]):
        rank_zero_warn("One of given dataloaders is None and it will be skipped.")

    # add samplers
    dataloaders = [
        self.auto_add_sampler(dl, train=False) for dl in dataloaders if dl is not None
    ]

    loader_num_batches = []

    # determine number of batches
    # datasets could be none, 1 or 2+
    if len(dataloaders) != 0:
        for i, dataloader in enumerate(dataloaders):
            num_batches = len(dataloader) if has_len(dataloader) else float("inf")
            self._worker_check(dataloader, f"{mode} dataloader {i}")

            # percent or num_steps
            limit_eval_batches = getattr(self, f"limit_{mode}_batches")

            # limit num batches either as a percent or num steps
            if isinstance(limit_eval_batches, int) or limit_eval_batches == 0.0:
                num_batches = min(num_batches, int(limit_eval_batches))
            elif num_batches != float("inf"):
                num_batches = int(num_batches * limit_eval_batches)
            elif limit_eval_batches != 1.0:
                raise MisconfigurationException(
                    "When using an IterableDataset for `limit_{mode}_batches`,"
                    f" `Trainer(limit_{mode}_batches)` must be `0.0`, `1.0` or an int. An int k specifies"
                    f" `num_{mode}_batches` to use."
                )

            if (
                num_batches == 0
                and limit_eval_batches > 0.0
                and isinstance(limit_eval_batches, float)
            ):
                min_pct = 1.0 / len(dataloader)
                raise MisconfigurationException(
                    f"you requested to check {limit_eval_batches} of the {mode} dataloader but"
                    f" {limit_eval_batches}*{num_batches} < 1. Please increase the limit_{mode}_batches."
                    f" Try at least limit_{mode}_batches={min_pct}"
                )

            loader_num_batches.append(num_batches)

    return loader_num_batches, dataloaders