Adds columns to the SFrame.  The number of elements in all columns must
        match every other column of the SFrame.

        If inplace == False (default) this operation does not modify the
        current SFrame, returning a new SFrame.

        If inplace == True, this operation modifies the current
        SFrame, returning self.

        Parameters
        ----------
        data : list[SArray] or SFrame
            The columns to add.

        column_names: list of string, optional
            A list of column names. All names must be specified. ``column_names`` is
            ignored if data is an SFrame.

        inplace : bool, optional. Defaults to False.
            Whether the SFrame is modified in place.

def add_columns(self, data, column_names=None, inplace=False):
        """
        Adds columns to the SFrame.  The number of elements in all columns must
        match every other column of the SFrame.

        If inplace == False (default) this operation does not modify the
        current SFrame, returning a new SFrame.

        If inplace == True, this operation modifies the current
        SFrame, returning self.

        Parameters
        ----------
        data : list[SArray] or SFrame
            The columns to add.

        column_names: list of string, optional
            A list of column names. All names must be specified. ``column_names`` is
            ignored if data is an SFrame.

        inplace : bool, optional. Defaults to False.
            Whether the SFrame is modified in place.
        """

        datalist = data
        if isinstance(data, SFrame):
            other = data
            datalist = [other.select_column(name) for name in other.column_names()]
            column_names = other.column_names()

            my_columns = set(self.column_names())
            for name in column_names:
                if name in my_columns:
                    raise ValueError("Column '" + name + "' already exists in current SFrame")
        else:
            if not _is_non_string_iterable(datalist):
                raise TypeError("datalist must be an iterable")
            if not _is_non_string_iterable(column_names):
                raise TypeError("column_names must be an iterable")

            if not all([isinstance(x, SArray) for x in datalist]):
                raise TypeError("Must give column as SArray")
            if not all([isinstance(x, str) for x in column_names]):
                raise TypeError("Invalid column name in list : must all be str")

        if inplace:
            for (data, name) in zip(datalist, column_names):
                self.add_column(data, name)
            return self
        else:
            return super(GFrame, self).add_column(datalist, column_names, inplace=inplace)