code: def test_multiple_pruning_callbacks(
      tmpdir, caplog, make_pruning_permanent: bool
  ):
      model = TestModel()
      pruning_kwargs = {
          "parameters_to_prune": [
              (model.layer.mlp_1, "weight"),
              (model.layer.mlp_3, "weight"),
          ],
          "verbose": 2,
          "make_pruning_permanent": make_pruning_permanent,
      }
      p1 = ModelPruning(
          "l1_unstructured",
          amount=0.5,
          apply_pruning=lambda e: not e % 2,
          **pruning_kwargs,
      )
      p2 = ModelPruning(
          "random_unstructured",
          amount=0.25,
          apply_pruning=lambda e: e % 2,
          **pruning_kwargs,
      )
  
      trainer = Trainer(
          default_root_dir=tmpdir,
          enable_progress_bar=False,
          enable_model_summary=False,
          enable_checkpointing=False,
          logger=False,
          limit_train_batches=10,
          limit_val_batches=2,
          max_epochs=3,
          callbacks=[p1, p2],
      )
      with caplog.at_level(INFO):
          trainer.fit(model)
  
      actual = [m.strip() for m in caplog.messages]
      actual = [m for m in actual if m.startswith("Applied")]
      percentage = r"\(\d+(?:\.\d+)?%\)"
      expected = [
          rf"Applied `L1Unstructured`. Pruned: \d+\/1122 {percentage} -> \d+\/1122 {percentage}",
          rf"Applied `L1Unstructured` to `Linear\(in_features=32, out_features=32, bias=True\).weight` with amount=0.5. Pruned: 0 \(0.00%\) -> \d+ {percentage}",  # noqa: E501
          rf"Applied `L1Unstructured` to `Linear\(in_features=32, out_features=2, bias=True\).weight` with amount=0.5. Pruned: 0 \(0.00%\) -> \d+ {percentage}",  # noqa: E501
          rf"Applied `RandomUnstructured`. Pruned: \d+\/1122 {percentage} -> \d+\/1122 {percentage}",
          rf"Applied `RandomUnstructured` to `Linear\(in_features=32, out_features=32, bias=True\).weight` with amount=0.25. Pruned: \d+ {percentage} -> \d+ {percentage}",  # noqa: E501
          rf"Applied `RandomUnstructured` to `Linear\(in_features=32, out_features=2, bias=True\).weight` with amount=0.25. Pruned: \d+ {percentage} -> \d+ {percentage}",  # noqa: E501
          rf"Applied `L1Unstructured`. Pruned: \d+\/1122 {percentage} -> \d+\/1122 {percentage}",
          rf"Applied `L1Unstructured` to `Linear\(in_features=32, out_features=32, bias=True\).weight` with amount=0.5. Pruned: \d+ {percentage} -> \d+ {percentage}",  # noqa: E501
          rf"Applied `L1Unstructured` to `Linear\(in_features=32, out_features=2, bias=True\).weight` with amount=0.5. Pruned: \d+ {percentage} -> \d+ {percentage}",  # noqa: E501
      ]
      expected = [re.compile(s) for s in expected]
      assert all(regex.match(s) for s, regex in zip(actual, expected))
  
      filepath = str(tmpdir / "foo.ckpt")
      trainer.save_checkpoint(filepath)
  
      model.load_state_dict(torch.load(filepath), strict=False)
      has_pruning = hasattr(model.layer.mlp_1, "weight_orig")
      assert not has_pruning if make_pruning_permanent else has_pruning
  
imports: import re
  from collections import OrderedDict
  from logging import INFO
  from typing import Union
  import pytest
  import torch
  import torch.nn.utils.prune
  from lightning.pytorch import Trainer, seed_everything
  from lightning.pytorch.callbacks import ModelCheckpoint, ModelPruning
  from lightning.pytorch.demos.boring_classes import BoringModel
  from lightning.pytorch.utilities.exceptions import MisconfigurationException
  from torch import nn
  from torch.nn import Sequential
  from tests_pytorch.helpers.runif import RunIf
label_desc: Use image node_id 8 for calling a global function with example usage: test_multiple_pruning_callbacks(tmpdir, caplog, make_pruning_permanent) without return types