Given an interval `start:stop`, return bins for intervals completely
    *containing* `start:stop`. The order is according to the bin level
    (starting with the smallest bins), and within a level according to the bin
    number (ascending).

    :arg int start, stop: Interval positions (zero-based, open-ended). If
      `stop` is not provided, the interval is assumed to be of length 1
      (equivalent to `stop = start + 1`).

    :return: All bins for intervals containing `start:stop`, ordered first
      according to bin level (ascending) and then according to bin number
      (ascending).
    :rtype: list(int)

    :raise OutOfRangeError: If `start:stop` exceeds the range of the binning
      scheme.

def containing_bins(start, stop=None):
    """
    Given an interval `start:stop`, return bins for intervals completely
    *containing* `start:stop`. The order is according to the bin level
    (starting with the smallest bins), and within a level according to the bin
    number (ascending).

    :arg int start, stop: Interval positions (zero-based, open-ended). If
      `stop` is not provided, the interval is assumed to be of length 1
      (equivalent to `stop = start + 1`).

    :return: All bins for intervals containing `start:stop`, ordered first
      according to bin level (ascending) and then according to bin number
      (ascending).
    :rtype: list(int)

    :raise OutOfRangeError: If `start:stop` exceeds the range of the binning
      scheme.
    """
    if stop is None:
        stop = start + 1

    max_bin = assign_bin(start, stop)
    return [bin for bin in overlapping_bins(start, stop) if bin <= max_bin]