# Buggy code
def fit(self, X, y, check_input=True):
    """Fit model with coordinate descent.

    Parameters
    -----------
    X : ndarray or scipy.sparse matrix, (n_samples, n_features)
        Data

    y : ndarray, shape (n_samples,) or (n_samples, n_targets)
        Target. Will be cast to X's dtype if necessary

    check_input : boolean, (default=True)
        Allow to bypass several input checking.
        Don't use this parameter unless you know what you do.

    Notes
    -----

    Coordinate descent is an algorithm that considers each column of
    data at a time hence it will automatically convert the X input
    as a Fortran-contiguous numpy array if necessary.

    To avoid memory re-allocation it is advised to allocate the
    initial data in memory directly using that format.
    """

    if self.alpha == 0:
        warnings.warn(
            "With alpha=0, this algorithm does not converge "
            "well. You are advised to use the LinearRegression "
            "estimator",
            stacklevel=2,
        )

    if isinstance(self.precompute, six.string_types):
        raise ValueError(
            "precompute should be one of True, False or"
            " array-like. Got %r" % self.precompute
        )

    # Remember if X is copied
    X_copied = False
    # We expect X and y to be float64 or float32 Fortran ordered arrays
    # when bypassing checks
    if check_input:
        X_copied = self.copy_X and self.fit_intercept
        X, y = check_X_y(
            X,
            y,
            accept_sparse="csc",
            order="F",
            dtype=[np.float64, np.float32],
            copy=X_copied,
            multi_output=True,
            y_numeric=True,
        )
        y = check_array(y, order="F", copy=False, dtype=X.dtype.type, ensure_2d=False)

    # Ensure copying happens only once, don't do it again if done above
    should_copy = self.copy_X and not X_copied
    X, y, X_offset, y_offset, X_scale, precompute, Xy = _pre_fit(
        X,
        y,
        None,
        self.precompute,
        self.normalize,
        self.fit_intercept,
        copy=should_copy,
    )
    if y.ndim == 1:
        y = y[:, np.newaxis]
    if Xy is not None and Xy.ndim == 1:
        Xy = Xy[:, np.newaxis]

    n_samples, n_features = X.shape
    n_targets = y.shape[1]

    if self.selection not in ["cyclic", "random"]:
        raise ValueError("selection should be either random or cyclic.")

    if not self.warm_start or not hasattr(self, "coef_"):
        coef_ = np.zeros((n_targets, n_features), dtype=X.dtype, order="F")
    else:
        coef_ = self.coef_
        if coef_.ndim == 1:
            coef_ = coef_[np.newaxis, :]

    dual_gaps_ = np.zeros(n_targets, dtype=X.dtype)
    self.n_iter_ = []

    for k in xrange(n_targets):
        if Xy is not None:
            this_Xy = Xy[:, k]
        else:
            this_Xy = None
        _, this_coef, this_dual_gap, this_iter = self.path(
            X,
            y[:, k],
            l1_ratio=self.l1_ratio,
            eps=None,
            n_alphas=None,
            alphas=[self.alpha],
            precompute=precompute,
            Xy=this_Xy,
            fit_intercept=False,
            normalize=False,
            copy_X=True,
            verbose=False,
            tol=self.tol,
            positive=self.positive,
            X_offset=X_offset,
            X_scale=X_scale,
            return_n_iter=True,
            coef_init=coef_[k],
            max_iter=self.max_iter,
            random_state=self.random_state,
            selection=self.selection,
            check_input=False,
        )
        coef_[k] = this_coef[:, 0]
        dual_gaps_[k] = this_dual_gap[0]
        self.n_iter_.append(this_iter[0])

    if n_targets == 1:
        self.n_iter_ = self.n_iter_[0]

    self.coef_, self.dual_gap_ = map(np.squeeze, [coef_, dual_gaps_])
    self._set_intercept(X_offset, y_offset, X_scale)

    # workaround since _set_intercept will cast self.coef_ into X.dtype
    self.coef_ = np.asarray(self.coef_, dtype=X.dtype)

    # return self for chaining fit and predict calls
    return self


# Traceback (AssertionError)
In [2]: %paste
import numpy as np
from sklearn import linear_model
est_intercept = linear_model.Lasso(fit_intercept=True)
est_intercept.fit(np.c_[np.ones(3)], np.ones(3))
assert est_intercept.coef_.shape  == (1,)



In [3]: %paste
import numpy as np
from sklearn import linear_model

est_no_intercept = linear_model.Lasso(fit_intercept=False)
est_no_intercept.fit(np.c_[np.ones(3)], np.ones(3))
assert est_no_intercept.coef_.shape  == (1,)


---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
<ipython-input-3-5ffa9cfd4df7> in <module>()
4 est_no_intercept = linear_model.Lasso(fit_intercept=False)
5 est_no_intercept.fit(np.c_[np.ones(3)], np.ones(3))
----> 6 assert est_no_intercept.coef_.shape  == (1,)

AssertionError:

# Fixed code
def fit(self, X, y, check_input=True):
    """Fit model with coordinate descent.

    Parameters
    -----------
    X : ndarray or scipy.sparse matrix, (n_samples, n_features)
        Data

    y : ndarray, shape (n_samples,) or (n_samples, n_targets)
        Target. Will be cast to X's dtype if necessary

    check_input : boolean, (default=True)
        Allow to bypass several input checking.
        Don't use this parameter unless you know what you do.

    Notes
    -----

    Coordinate descent is an algorithm that considers each column of
    data at a time hence it will automatically convert the X input
    as a Fortran-contiguous numpy array if necessary.

    To avoid memory re-allocation it is advised to allocate the
    initial data in memory directly using that format.
    """

    if self.alpha == 0:
        warnings.warn(
            "With alpha=0, this algorithm does not converge "
            "well. You are advised to use the LinearRegression "
            "estimator",
            stacklevel=2,
        )

    if isinstance(self.precompute, six.string_types):
        raise ValueError(
            "precompute should be one of True, False or"
            " array-like. Got %r" % self.precompute
        )

    # Remember if X is copied
    X_copied = False
    # We expect X and y to be float64 or float32 Fortran ordered arrays
    # when bypassing checks
    if check_input:
        X_copied = self.copy_X and self.fit_intercept
        X, y = check_X_y(
            X,
            y,
            accept_sparse="csc",
            order="F",
            dtype=[np.float64, np.float32],
            copy=X_copied,
            multi_output=True,
            y_numeric=True,
        )
        y = check_array(y, order="F", copy=False, dtype=X.dtype.type, ensure_2d=False)

    # Ensure copying happens only once, don't do it again if done above
    should_copy = self.copy_X and not X_copied
    X, y, X_offset, y_offset, X_scale, precompute, Xy = _pre_fit(
        X,
        y,
        None,
        self.precompute,
        self.normalize,
        self.fit_intercept,
        copy=should_copy,
    )
    if y.ndim == 1:
        y = y[:, np.newaxis]
    if Xy is not None and Xy.ndim == 1:
        Xy = Xy[:, np.newaxis]

    n_samples, n_features = X.shape
    n_targets = y.shape[1]

    if self.selection not in ["cyclic", "random"]:
        raise ValueError("selection should be either random or cyclic.")

    if not self.warm_start or not hasattr(self, "coef_"):
        coef_ = np.zeros((n_targets, n_features), dtype=X.dtype, order="F")
    else:
        coef_ = self.coef_
        if coef_.ndim == 1:
            coef_ = coef_[np.newaxis, :]

    dual_gaps_ = np.zeros(n_targets, dtype=X.dtype)
    self.n_iter_ = []

    for k in xrange(n_targets):
        if Xy is not None:
            this_Xy = Xy[:, k]
        else:
            this_Xy = None
        _, this_coef, this_dual_gap, this_iter = self.path(
            X,
            y[:, k],
            l1_ratio=self.l1_ratio,
            eps=None,
            n_alphas=None,
            alphas=[self.alpha],
            precompute=precompute,
            Xy=this_Xy,
            fit_intercept=False,
            normalize=False,
            copy_X=True,
            verbose=False,
            tol=self.tol,
            positive=self.positive,
            X_offset=X_offset,
            X_scale=X_scale,
            return_n_iter=True,
            coef_init=coef_[k],
            max_iter=self.max_iter,
            random_state=self.random_state,
            selection=self.selection,
            check_input=False,
        )
        coef_[k] = this_coef[:, 0]
        dual_gaps_[k] = this_dual_gap[0]
        self.n_iter_.append(this_iter[0])

    if n_targets == 1:
        self.n_iter_ = self.n_iter_[0]
        self.coef_ = coef_[0]
        self.dual_gap_ = dual_gaps_[0]
    else:
        self.coef_ = coef_
        self.dual_gap_ = dual_gaps_

    self._set_intercept(X_offset, y_offset, X_scale)

    # workaround since _set_intercept will cast self.coef_ into X.dtype
    self.coef_ = np.asarray(self.coef_, dtype=X.dtype)

    # return self for chaining fit and predict calls
    return self