Repository: Lightning-AI/pytorch-lightning
File: tests/trainer/test_optimizers.py (Python)

Code before:
        'lr_scheduler': {
            'scheduler': scheduler,
            'monitor': 'giraffe',
            'strict': False,
        },
    }
    with pytest.warns(
        RuntimeWarning, match=r'ReduceLROnPlateau conditioned on metric .* which is not available but strict'
    ):
        assert trainer.fit(model)


def test_unknown_configure_optimizers_raises(tmpdir):
    """
    Test exception with an unsupported configure_optimizers return
    """
    model = EvalModelTemplate()
    model.configure_optimizers = lambda: 1
    trainer = Trainer(default_root_dir=tmpdir, fast_dev_run=True)
    msg = """Unknown configuration for model optimizers. Output from `model.configure_optimizers()` should either be:
 * `torch.optim.Optimizer`
 * [`torch.optim.Optimizer`]
 * ([`torch.optim.Optimizer`], [`torch.optim.lr_scheduler`])
 * {"optimizer": `torch.optim.Optimizer`, (optional) "lr_scheduler": `torch.optim.lr_scheduler`}
 * A list of the previously described dict format, with an optional "frequency" key (int)"""
    with pytest.raises(MisconfigurationException, match=escape(msg)):
        trainer.fit(model)


def test_lr_scheduler_with_extra_keys_warns(tmpdir):
    """
    Test warning when lr_scheduler dict has extra keys
    """
    model = EvalModelTemplate()
    optimizer = torch.optim.Adam(model.parameters())
    model.configure_optimizers = lambda: {
        'optimizer': optimizer,
        'lr_scheduler': {
            'scheduler': torch.optim.lr_scheduler.StepLR(optimizer, 1),
            'foo': 1,
            'bar': 2,
        },
    }
    trainer = Trainer(default_root_dir=tmpdir, fast_dev_run=True)
    with pytest.warns(RuntimeWarning, match=r'Found unsupported keys in the lr scheduler dict: \[.+\]'):
        trainer.fit(model)


def test_lr_scheduler_with_no_actual_scheduler_raises(tmpdir):
    """
    Test exception when lr_scheduler dict has no scheduler

Review comment (performance):
```suggestion
    with pytest.raises(MisconfigurationException, match="Unknown configuration for model optimizers."):
```
you don't need to give it the full exact message if it's not ambigious. makes it easier to read the test

Code after:
        'lr_scheduler': {'scheduler': scheduler, 'monitor': 'giraffe', 'strict': True},
    }
    with pytest.raises(
        MisconfigurationException,
        match=r'ReduceLROnPlateau conditioned on metric .* which is not available\. Available metrics are:',
    ):
        trainer.fit(model)

    model.configure_optimizers = lambda: {
        'optimizer': optimizer,
        'lr_scheduler': {
            'scheduler': scheduler,
            'monitor': 'giraffe',
            'strict': False,
        },
    }
    with pytest.warns(
        RuntimeWarning, match=r'ReduceLROnPlateau conditioned on metric .* which is not available but strict'
    ):
        assert trainer.fit(model)


def test_unknown_configure_optimizers_raises(tmpdir):
    """
    Test exception with an unsupported configure_optimizers return
    """
    model = EvalModelTemplate()
    model.configure_optimizers = lambda: 1
    trainer = Trainer(default_root_dir=tmpdir, fast_dev_run=True)
    with pytest.raises(MisconfigurationException, match="Unknown configuration for model optimizers"):
        trainer.fit(model)


def test_lr_scheduler_with_extra_keys_warns(tmpdir):
    """
    Test warning when lr_scheduler dict has extra keys
    """
    model = EvalModelTemplate()
    optimizer = torch.optim.Adam(model.parameters())
    model.configure_optimizers = lambda: {
        'optimizer': optimizer,
        'lr_scheduler': {
            'scheduler': torch.optim.lr_scheduler.StepLR(optimizer, 1),
            'foo': 1,
            'bar': 2,
        },
    }
    trainer = Trainer(default_root_dir=tmpdir, fast_dev_run=True)
    with pytest.warns(RuntimeWarning, match=r'Found unsupported keys in the lr scheduler dict: \[.+\]'):
        trainer.fit(model)