# Buggy code
def get_domain(self, domain, data):
    """Create domain (and dataset) from changes made in the widget.

    Parameters
    ----------
    domain : old domain
    data : source data

    Returns
    -------
    (new_domain, [attribute_columns, class_var_columns, meta_columns])
    """
    variables = self.model().variables
    places = [[], [], []]  # attributes, class_vars, metas
    cols = [[], [], []]  # Xcols, Ycols, Mcols

    def is_missing(x):
        return str(x) in ("nan", "")

    for (name, tpe, place, _, _), (orig_var, orig_plc) in zip(
        variables,
        chain(
            [(at, Place.feature) for at in domain.attributes],
            [(cl, Place.class_var) for cl in domain.class_vars],
            [(mt, Place.meta) for mt in domain.metas],
        ),
    ):
        if place == Place.skip:
            continue
        if orig_plc == Place.meta:
            col_data = data[:, orig_var].metas
        elif orig_plc == Place.class_var:
            col_data = data[:, orig_var].Y
        else:
            col_data = data[:, orig_var].X
        col_data = col_data.ravel()
        if name == orig_var.name and tpe == type(orig_var):
            var = orig_var
        elif tpe == type(orig_var):
            # change the name so that all_vars will get the correct name
            orig_var.name = name
            var = orig_var
        elif tpe == DiscreteVariable:
            values = list(str(i) for i in np.unique(col_data) if not is_missing(i))
            var = tpe(name, values)
            col_data = [
                np.nan if is_missing(x) else values.index(str(x)) for x in col_data
            ]
        elif tpe == StringVariable and type(orig_var) == DiscreteVariable:
            var = tpe(name)
            col_data = [
                orig_var.repr_val(x) if not np.isnan(x) else "" for x in col_data
            ]
        else:
            var = tpe(name)
        places[place].append(var)
        cols[place].append(col_data)
    domain = Domain(*places)
    return domain, cols


# Traceback (AttributeError)
Traceback (most recent call last):
File "/Users/Niko/Projects/orange3/Orange/widgets/data/owfile.py", line 269, in browse_file
self.load_data()
File "/Users/Niko/Projects/orange3/Orange/widgets/data/owfile.py", line 322, in load_data
self.apply_domain_edit()  # sends data
File "/Users/Niko/Projects/orange3/Orange/widgets/data/owfile.py", line 404, in apply_domain_edit
domain, cols = self.domain_editor.get_domain(self.data.domain, self.data)
File "/Users/Niko/Projects/orange3/Orange/widgets/utils/domaineditor.py", line 231, in get_domain
col_data = col_data.ravel()
File "/Users/Niko/anaconda/envs/temporary/lib/python3.6/site-packages/scipy/sparse/base.py", line 576, in __getattr__
raise AttributeError(attr + " not found")
AttributeError: ravel not found

# Fixed code
def get_domain(self, domain, data):
    """Create domain (and dataset) from changes made in the widget.

    Parameters
    ----------
    domain : old domain
    data : source data

    Returns
    -------
    (new_domain, [attribute_columns, class_var_columns, meta_columns])
    """
    variables = self.model().variables
    places = [[], [], []]  # attributes, class_vars, metas
    cols = [[], [], []]  # Xcols, Ycols, Mcols

    for (name, tpe, place, _, _), (orig_var, orig_plc) in zip(
        variables,
        chain(
            [(at, Place.feature) for at in domain.attributes],
            [(cl, Place.class_var) for cl in domain.class_vars],
            [(mt, Place.meta) for mt in domain.metas],
        ),
    ):
        if place == Place.skip:
            continue

        col_data = self._get_column(data, orig_var, orig_plc)
        is_sparse = sp.issparse(col_data)
        if name == orig_var.name and tpe == type(orig_var):
            var = orig_var
        elif tpe == type(orig_var):
            # change the name so that all_vars will get the correct name
            orig_var.name = name
            var = orig_var
        elif tpe == DiscreteVariable:
            values = list(str(i) for i in unique(col_data) if not self._is_missing(i))
            var = tpe(name, values)
            col_data = [
                np.nan if self._is_missing(x) else values.index(str(x))
                for x in self._iter_vals(col_data)
            ]
            col_data = self._to_column(col_data, is_sparse)
        elif tpe == StringVariable and type(orig_var) == DiscreteVariable:
            var = tpe(name)
            col_data = [
                orig_var.repr_val(x) if not np.isnan(x) else ""
                for x in self._iter_vals(col_data)
            ]
            # don't obey sparsity for StringVariable since they are
            # in metas which are transformed to dense below
            col_data = self._to_column(col_data, False, dtype=object)
        else:
            var = tpe(name)
        places[place].append(var)
        cols[place].append(col_data)

    # merge columns for X, Y and metas
    feats = cols[Place.feature]
    X = self._merge(feats) if len(feats) else np.empty((len(data), 0))
    Y = self._merge(cols[Place.class_var], force_dense=True)
    m = self._merge(cols[Place.meta], force_dense=True)
    domain = Domain(*places)
    return domain, [X, Y, m]