def _wrap_attr_method(method: Callable, tag: _WrapAttrTag) -> Callable:
    """Wraps the ``__setattr__`` or ``__delattr__`` method of classes (currently :class:`~torch.utils.data.DataLoader`
    and :class:`~torch.utils.data.BatchSampler`) in order to enable re- instantiation of custom subclasses."""

    @functools.wraps(method)
    def wrapper(obj: Any, *args: Any) -> None:
        # First, let's find out if we're the first in inheritance chain calling the patched method.
        name, *_ = args
        prev_call_name, prev_call_method = getattr(obj, "__pl_current_call", (None, "method"))
        first_call = not (prev_call_name == name and prev_call_method == tag)

        # Then mark the current called method
        object.__setattr__(obj, "__pl_current_call", (name, tag))

        # call original method
        method(obj, *args)
        if first_call and not getattr(obj, "__pl_inside_init", True):
            # and save the value it was called with to the internal list,
            # if we're outside of __init__ and the original call did not fail and we're the first call
            attrs_record = getattr(obj, "__pl_attrs_record", [])
            attrs_record.append((args, tag))
            object.__setattr__(obj, "__pl_attrs_record", attrs_record)
        object.__setattr__(obj, "__pl_current_call", (prev_call_name, prev_call_method))

    return wrapper
Wraps the ``__setattr__`` or ``__delattr__`` method of classes (currently :class:`~torch.utils.data.DataLoader`
    and :class:`~torch.utils.data.BatchSampler`) in order to enable re- instantiation of custom subclasses.
src/lightning/fabric/utilities/data.py