docs: def permutation_to_block_permutations(permutation):
      """If possible, decompose a permutation into a sequence of permutations
      each acting on individual ranges of the full range of indices.
      E.g.
  
          ``(1,2,0,3,5,4) --> (1,2,0) [+] (0,2,1)``
  
      :param permutation: A valid permutation image tuple ``s = (s_0,...s_n)`` with ``n > 0``
      :type permutation: tuple
      :return: A list of permutation tuples ``[t = (t_0,...,t_n1), u = (u_0,...,u_n2),..., z = (z_0,...,z_nm)]`` such that ``s = t [+] u [+] ... [+] z``
      :rtype: list of tuples
      :raise: ValueError
      """
      if len(permutation) == 0 or not check_permutation(permutation):
          raise BadPermutationError()
  
      cycles = permutation_to_disjoint_cycles(permutation)
  
      if len(cycles) == 1:
          return (permutation,)
      current_block_start = cycles[0][0]
      current_block_end = max(cycles[0])
      current_block_cycles = [cycles[0]]
      res_permutations = []
      for c in cycles[1:]:
          if c[0] > current_block_end:
              res_permutations.append(permutation_from_disjoint_cycles(current_block_cycles, current_block_start))
              assert sum(map(len, current_block_cycles)) == current_block_end - current_block_start + 1
              current_block_start = c[0]
              current_block_end = max(c)
              current_block_cycles = [c]
          else:
              current_block_cycles.append(c)
              if max(c) > current_block_end:
                  current_block_end = max(c)
  
      res_permutations.append(permutation_from_disjoint_cycles(current_block_cycles, current_block_start))
  
      assert sum(map(len, current_block_cycles)) == current_block_end - current_block_start + 1
      assert sum(map(len, res_permutations)) == len(permutation)
  
      return res_permutations