docs: def intersection(self, other):
          """
          Returns a new range containing all points shared by both ranges. If no
          points are shared an empty range is returned.
  
              >>> intrange(1, 5).intersection(intrange(1, 10))
              intrange([1,5))
              >>> intrange(1, 5).intersection(intrange(5, 10))
              intrange(empty)
              >>> intrange(1, 10).intersection(intrange(5, 10))
              intrange([5,10))
  
          This is the same as the ``+`` operator for two ranges in PostgreSQL.
  
          :param other: Range to interect with.
          :return: A new range that is the intersection between this and `other`.
          """
  
          if not self.is_valid_range(other):
              msg = "Unsupported type to test for intersection '{.__class__.__name__}'"
              raise TypeError(msg.format(other))
  
          # Handle ranges not intersecting
          if not self or not other or not self.overlap(other):
              return self.empty()
  
          lower_end_span = self if self.startsafter(other) else other
          upper_end_span = self if self.endsbefore(other) else other
  
          return lower_end_span.replace(
              upper=upper_end_span.upper,
              upper_inc=upper_end_span.upper_inc)