def offset(self, offset):
        """
        Shift the range to the left or right with the given offset

            >>> intrange(0, 5).offset(5)
            intrange([5,10))
            >>> intrange(5, 10).offset(-5)
            intrange([0,5))
            >>> intrange.empty().offset(5)
            intrange(empty)

        Note that range objects are immutable and are never modified in place.

        :param offset: Scalar to offset by.

        .. versionadded:: 0.1.3
        """

        # If range is empty it can't be offset
        if not self:
            return self

        offset_type = self.type if self.offset_type is None else self.offset_type

        if offset is not None and not isinstance(offset, offset_type):
            raise TypeError((
                "Invalid type for offset '{offset_type.__name__}'"
                " expected '{expected_type.__name__}'").format(
                    expected_type=offset_type,
                    offset_type=offset.__class__))

        lower = None if self.lower is None else self.lower + offset
        upper = None if self.upper is None else self.upper + offset

        return self.replace(lower=lower, upper=upper)