Repository: Lightning-AI/pytorch-lightning
File: src/lightning/fabric/fabric.py (Python)

Code before:
        )

        if hasattr(original_module, "_fabric"):  # this is probably a LightningModule
            original_module._fabric = self
            if original_module not in self._callbacks:
                self._callbacks.append(original_module)

        self._models_setup += 1
        return module

    def setup_optimizers(self, *optimizers: Optimizer) -> Union[_FabricOptimizer, tuple[_FabricOptimizer, ...]]:
        r"""Set up one or more optimizers for accelerated training.

        Some strategies do not allow setting up model and optimizer independently. For them, you should call
        ``.setup(model, optimizer, ...)`` instead to jointly set them up.

        Args:
            *optimizers: One or more optimizers to set up. Must provide at least one optimizer.

        Returns:
            If a single optimizer is passed, returns the wrapped optimizer. If multiple optimizers are passed,
            returns a tuple of wrapped optimizers in the same order they were passed in.

        Raises:
            RuntimeError: If using DeepSpeed or XLA strategies, which require joint model-optimizer setup.
            ValueError: If no optimizers are provided.

        Note:
            This method cannot be used with DeepSpeed or XLA strategies. Use :meth:`setup` instead for those strategies.

        Example::

            # Single optimizer
            optimizer = fabric.setup_optimizers(optimizer)

            # Multiple optimizers
            opt1, opt2 = fabric.setup_optimizers(opt1, opt2)

        """
        self._validate_setup_optimizers(optimizers)
        optimizers = [self._strategy.setup_optimizer(optimizer) for optimizer in optimizers]
        optimizers = [
            _FabricOptimizer(optimizer=optimizer, strategy=self._strategy, callbacks=self._callbacks)
            for optimizer in optimizers
        ]
        return optimizers[0] if len(optimizers) == 1 else tuple(optimizers)

    def setup_dataloaders(
        self, *dataloaders: DataLoader, use_distributed_sampler: bool = True, move_to_device: bool = True
    ) -> Union[DataLoader, list[DataLoader]]:
        r"""Set up one or multiple dataloaders for accelerated training. If you need different settings for each

Review comment (performance):
The ValueError description is inaccurate. The method signature shows `*optimizers: Optimizer` which means zero or more optimizers are allowed, but the documentation states 'Must provide at least one optimizer' and lists ValueError for no optimizers. This creates a contradiction.

Code after:
        )

        if hasattr(original_module, "_fabric"):  # this is probably a LightningModule
            original_module._fabric = self
            if original_module not in self._callbacks:
                self._callbacks.append(original_module)

        self._models_setup += 1
        return module

    def setup_optimizers(self, *optimizers: Optimizer) -> Union[_FabricOptimizer, tuple[_FabricOptimizer, ...]]:
        r"""Set up one or more optimizers for accelerated training.

        Some strategies do not allow setting up model and optimizer independently. For them, you should call
        ``.setup(model, optimizer, ...)`` instead to jointly set them up.

        Args:
            *optimizers: One or more optimizers to set up. Must provide at least one optimizer.

        Returns:
            If a single optimizer is passed, returns the wrapped optimizer. If multiple optimizers are passed,
            returns a tuple of wrapped optimizers in the same order they were passed in.

        Raises:
            RuntimeError: If using DeepSpeed or XLA strategies, which require joint model-optimizer setup.

        Note:
            This method cannot be used with DeepSpeed or XLA strategies. Use :meth:`setup` instead for those strategies.

        Example::

            # Single optimizer
            optimizer = fabric.setup_optimizers(optimizer)

            # Multiple optimizers
            opt1, opt2 = fabric.setup_optimizers(opt1, opt2)

        """
        self._validate_setup_optimizers(optimizers)
        optimizers = [self._strategy.setup_optimizer(optimizer) for optimizer in optimizers]
        optimizers = [
            _FabricOptimizer(optimizer=optimizer, strategy=self._strategy, callbacks=self._callbacks)
            for optimizer in optimizers
        ]
        return optimizers[0] if len(optimizers) == 1 else tuple(optimizers)

    def setup_dataloaders(
        self, *dataloaders: DataLoader, use_distributed_sampler: bool = True, move_to_device: bool = True
    ) -> Union[DataLoader, list[DataLoader]]:
        r"""Set up one or multiple dataloaders for accelerated training. If you need different settings for each
        dataloader, call this method individually for each one.