Manual assignment of a collection of (stopped) Times objects as a parallel
    subdivision of a running timer.

    Notes:
        An example sequence of proper usage:

            1. Stamp in master process.
            2. Run timed sub-processes.
            3. Get timing data from sub-processes into master.
            4. Attach timing data (i.e. list of Times objects) in master using this method.
            5. Stamp in master process.

        To stamp in the master between steps 1 and 5, it is recommended to
        subdivide() between steps 1 and 2, and end that subdivision before
        attaching, or else the master stamp will not reflect the sub-process
        time.

    Args:
        par_name (any): Identifier for the collection, passed through str()
        par_times (list or tuple): Collection of Times data objects.

    Raises:
        TypeError: If par_times not a list or tuple of Times data objects.

def attach_par_subdivision(par_name, par_times):
    """
    Manual assignment of a collection of (stopped) Times objects as a parallel
    subdivision of a running timer.

    Notes:
        An example sequence of proper usage:

            1. Stamp in master process.
            2. Run timed sub-processes.
            3. Get timing data from sub-processes into master.
            4. Attach timing data (i.e. list of Times objects) in master using this method.
            5. Stamp in master process.

        To stamp in the master between steps 1 and 5, it is recommended to
        subdivide() between steps 1 and 2, and end that subdivision before
        attaching, or else the master stamp will not reflect the sub-process
        time.

    Args:
        par_name (any): Identifier for the collection, passed through str()
        par_times (list or tuple): Collection of Times data objects.

    Raises:
        TypeError: If par_times not a list or tuple of Times data objects.
    """
    t = timer()
    if not isinstance(par_times, (list, tuple)):
        raise TypeError("Expected list or tuple for param 'par_times'.")
    for times in par_times:
        if not isinstance(times, Times):
            raise TypeError("Expected each element of param 'par_times' to be Times object.")
        assert times.total > 0., "An attached par subdivision has total time 0, appears empty."
    par_name = str(par_name)
    sub_with_max_tot = max(par_times, key=lambda x: x.total)
    f.r.self_agg += sub_with_max_tot.self_agg
    if par_name not in f.t.par_subdvsn_awaiting:
        f.t.par_subdvsn_awaiting[par_name] = []
        for times in par_times:
            times_copy = copy.deepcopy(times)
            times_copy.parent = f.r
            times_copy.par_in_parent = par_name
            f.t.par_subdvsn_awaiting[par_name].append(times_copy)
    else:
        for new_sub in par_times:
            is_prev_sub = False
            for old_sub in f.t.par_subdvsn_awaiting[par_name]:
                if old_sub.name == new_sub.name:
                    is_prev_sub = True
                    break
            if is_prev_sub:
                merge.merge_times(old_sub, new_sub)
            else:
                new_sub_copy = copy.deepcopy(new_sub)
                new_sub_copy.parent = f.r
                new_sub_copy.par_in_parent = par_name
                f.t.par_subdvsn_awaiting[par_name].append(new_sub_copy)
    f.t.self_cut += timer() - t