def union(self, other):
        """
        Merges this range with a given range.

            >>> intrange(1, 5).union(intrange(5, 10))
            intrange([1,10))
            >>> intrange(1, 10).union(intrange(5, 15))
            intrange([1,15))

        Two ranges can not be merged if the resulting range would be split in
        two. This happens when the two sets are neither adjacent nor overlaps.

            >>> intrange(1, 5).union(intrange(10, 15))
            Traceback (most recent call last):
              File "<stdin>", line 1, in <module>
            ValueError: Ranges must be either adjacent or overlapping

        This does not modify the range in place.

        This is the same as the ``+`` operator for two ranges in PostgreSQL.

        :param other: Range to merge with.
        :return: A new range that is the union of this and `other`.
        :raises ValueError: If `other` can not be merged with this range.
        """

        if not self.is_valid_range(other):
            msg = "Unsupported type to test for union '{.__class__.__name__}'"
            raise TypeError(msg.format(other))

        # Optimize empty ranges
        if not self:
            return other
        elif not other:
            return self

        # Order ranges to simplify checks
        if self < other:
            a, b = self, other
        else:
            a, b = other, self

        if (a.upper < b.lower or a.upper == b.lower and not
                a.upper_inc and not b.lower_inc) and not a.adjacent(b):
            raise ValueError("Ranges must be either adjacent or overlapping")

        # a.lower is guaranteed to be the lower bound, but either a.upper or
        # b.upper can be the upper bound
        if a.upper == b.upper:
            upper = a.upper
            upper_inc = a.upper_inc or b.upper_inc
        elif a.upper < b.upper:
            upper = b.upper
            upper_inc = b.upper_inc
        else:
            upper = a.upper
            upper_inc = a.upper_inc

        return self.__class__(a.lower, upper, a.lower_inc, upper_inc)
def union ( self , other ) : if not self . is_valid_range ( other ) : msg = "Unsupported type to test for union '{.__class__.__name__}'" raise TypeError ( msg . format ( other ) ) if not self : return other elif not other : return self if self < other : a , b = self , other else : a , b = other , self if ( a . upper < b . lower or a . upper == b . lower and not a . upper_inc and not b . lower_inc ) and not a . adjacent ( b ) : raise ValueError ( "Ranges must be either adjacent or overlapping" ) if a . upper == b . upper : upper = a . upper upper_inc = a . upper_inc or b . upper_inc elif a . upper < b . upper : upper = b . upper upper_inc = b . upper_inc else : upper = a . upper upper_inc = a . upper_inc return self . __class__ ( a . lower , upper , a . lower_inc , upper_inc )
Merges this range with a given range.

            >>> intrange(1, 5).union(intrange(5, 10))
            intrange([1,10))
            >>> intrange(1, 10).union(intrange(5, 15))
            intrange([1,15))

        Two ranges can not be merged if the resulting range would be split in
        two. This happens when the two sets are neither adjacent nor overlaps.

            >>> intrange(1, 5).union(intrange(10, 15))
            Traceback (most recent call last):
              File "<stdin>", line 1, in <module>
            ValueError: Ranges must be either adjacent or overlapping

        This does not modify the range in place.

        This is the same as the ``+`` operator for two ranges in PostgreSQL.

        :param other: Range to merge with.
        :return: A new range that is the union of this and `other`.
        :raises ValueError: If `other` can not be merged with this range.