def _base_typed(obj):
    """
    Improved version of https://stackoverflow.com/a/62420097
    """
    T = type(obj)
    from_numpy = T.__module__ == "numpy"
    from_pytorch = T.__module__ == "torch"

    if from_numpy or from_pytorch:
        return obj.tolist()

    if (
        T in BASE_TYPES
        or callable(obj)
        or ((from_numpy or from_pytorch) and not isinstance(T, Iterable))
    ):
        return obj

    if isinstance(obj, Dict):
        return {_base_typed(k): _base_typed(v) for k, v in obj.items()}
    elif isinstance(obj, Iterable):
        base_items = [_base_typed(item) for item in obj]
        return base_items if (from_numpy or from_pytorch) else T(base_items)

    d = obj if T is dict else obj.__dict__

    return {k: _base_typed(v) for k, v in d.items()}

    Improved version of https://stackoverflow.com/a/62420097
    
avalanche/distributed/distributed_helper.py