docs: def mip_bipartitions(mechanism, purview, node_labels=None):
      r"""Return an generator of all |small_phi| bipartitions of a mechanism over
      a purview.
  
      Excludes all bipartitions where one half is entirely empty, *e.g*::
  
           A     ∅
          ─── ✕ ───
           B     ∅
  
      is not valid, but ::
  
           A     ∅
          ─── ✕ ───
           ∅     B
  
      is.
  
      Args:
          mechanism (tuple[int]): The mechanism to partition
          purview (tuple[int]): The purview to partition
  
      Yields:
          Bipartition: Where each bipartition is::
  
              bipart[0].mechanism   bipart[1].mechanism
              ─────────────────── ✕ ───────────────────
              bipart[0].purview     bipart[1].purview
  
      Example:
          >>> mechanism = (0,)
          >>> purview = (2, 3)
          >>> for partition in mip_bipartitions(mechanism, purview):
          ...     print(partition, '\n')  # doctest: +NORMALIZE_WHITESPACE
           ∅     0
          ─── ✕ ───
           2     3
          <BLANKLINE>
           ∅     0
          ─── ✕ ───
           3     2
          <BLANKLINE>
           ∅     0
          ─── ✕ ───
          2,3    ∅
      """
      numerators = bipartition(mechanism)
      denominators = directed_bipartition(purview)
  
      for n, d in product(numerators, denominators):
          if (n[0] or d[0]) and (n[1] or d[1]):
              yield Bipartition(Part(n[0], d[0]), Part(n[1], d[1]),
                                node_labels=node_labels)