code: def unpack_frames(b, *, remainder=False, partial=False):
      """Unpack bytes into a sequence of frames
  
      This assumes that length information is at the front of the bytestring,
      as performed by pack_frames
  
      Parameters
      ----------
      b:
          packed frames, as returned by :func:`pack_frames`
      remainder:
          If True, return one extra frame at the end which is the continuation of a
          stream created by concatenating multiple calls to :func:`pack_frames`.
          This last frame will be empty at the end of the stream.
      partial:
          If True, allow for b to contain less frames than what the preamble indicates;
          return a tuple of ([frames so far], [lengths of missing frames])
  
      See Also
      --------
      pack_frames
      """
      b = memoryview(b)
  
      fmt = "Q"
      fmt_size = struct.calcsize(fmt)
  
      (n_frames,) = struct.unpack_from(fmt, b)
      lengths = struct.unpack_from(f"{n_frames}{fmt}", b, fmt_size)
  
      frames = []
      start = fmt_size * (1 + n_frames)
      nb = b.nbytes
      end = 0
      missing_lengths = []
      for length in lengths:
          if partial and start == nb:
              missing_lengths.extend(lengths[len(frames) :])
              break
  
          end = start + length
          frames.append(b[start:end])
          start = end
      assert end <= nb
  
      if remainder:
          frames.append(b[start:])
  
      if partial:
          return frames, missing_lengths
      else:
          return frames
  
file_path: distributed/distributed/protocol/utils.py
imports: from __future__ import annotations
  import ctypes
  import struct
  from collections.abc import Collection, Iterable, Sequence
  from typing import Literal, overload
  import dask
  from distributed.utils import nbytes
label_desc: Use image node_id 7 for calling a global function with example usage: unpack_frames(b) and returns: frames,  missing_lengths, frames