<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def transfer(self, data):
 """Shift out `data` and return shifted in data. Args: data (bytes, bytearray, list):
 a byte array or list of 8-bit integers to shift out. Returns: bytes, bytearray, list: data shifted in. Raises: SPIError: if an I/O or OS error occurs. TypeError: if `data` type is invalid. ValueError: if data is not valid bytes. """

        if not isinstance(data, (bytes, bytearray, list)):
            raise TypeError("Invalid data type, should be bytes, bytearray, or list.")

        # Create mutable array
        try:
            buf = array.array('B', data)
        except OverflowError:
            raise ValueError("Invalid data bytes.")

        buf_addr, buf_len = buf.buffer_info()

        # Prepare transfer structure
        spi_xfer = _CSpiIocTransfer()
        spi_xfer.tx_buf = buf_addr
        spi_xfer.rx_buf = buf_addr
        spi_xfer.len = buf_len

        # Transfer
        try:
            fcntl.ioctl(self._fd, SPI._SPI_IOC_MESSAGE_1, spi_xfer)
        except OSError as e:
            raise SPIError(e.errno, "SPI transfer: " + e.strerror)

        # Return shifted out data with the same type as shifted in data
        if isinstance(data, bytes):
            return bytes(bytearray(buf))
        elif isinstance(data, bytearray):
            return bytearray(buf)
        elif isinstance(data, list):
            return buf.tolist()