code: def _mk_range_bucket(name, n1, n2, r1, r2):
      
      d = {}
      if r1 is not None:
          d[n1] = r1
      if r2 is not None:
          d[n2] = r2
      if not d:
          raise TypeError('Must specify at least one range boundary!')
      d['name'] = name
      return d
docs: Create a named range specification for encoding.
  
      :param name: The name of the range as it should appear in the result
      :param n1: The name of the lower bound of the range specifier
      :param n2: The name of the upper bound of the range specified
      :param r1: The value of the lower bound (user value)
      :param r2: The value of the upper bound (user value)
      :return: A dictionary containing the range bounds. The upper and lower
          bounds are keyed under ``n1`` and ``n2``.
  
      More than just a simple wrapper, this will not include any range bound
      which has a user value of `None`. Likewise it will raise an exception if
      both range values are ``None``.