# Buggy code
def fit(self, data, *args, **kwds):
    floc = kwds.get("floc", None)

    if floc is None:
        # loc is not fixed.  Use the default fit method.
        return super(gamma_gen, self).fit(data, *args, **kwds)

    # We already have this value, so just pop it from kwds.
    kwds.pop("floc", None)

    f0 = _get_fixed_fit_value(kwds, ["f0", "fa", "fix_a"])
    fscale = kwds.pop("fscale", None)

    _remove_optimizer_parameters(kwds)

    # Special case: loc is fixed.

    if f0 is not None and fscale is not None:
        # This check is for consistency with `rv_continuous.fit`.
        # Without this check, this function would just return the
        # parameters that were given.
        raise ValueError("All parameters fixed. There is nothing to optimize.")

    # Fixed location is handled by shifting the data.
    data = np.asarray(data)
    if np.any(data <= floc):
        raise FitDataError("gamma", lower=floc, upper=np.inf)
    if floc != 0:
        # Don't do the subtraction in-place, because `data` might be a
        # view of the input array.
        data = data - floc
    xbar = data.mean()

    # Three cases to handle:
    # * shape and scale both free
    # * shape fixed, scale free
    # * shape free, scale fixed

    if fscale is None:
        # scale is free
        if f0 is not None:
            # shape is fixed
            a = f0
        else:
            # shape and scale are both free.
            # The MLE for the shape parameter `a` is the solution to:
            # np.log(a) - sc.digamma(a) - np.log(xbar) +
            #                             np.log(data.mean) = 0
            s = np.log(xbar) - np.log(data).mean()
            func = lambda a: np.log(a) - sc.digamma(a) - s
            aest = (3 - s + np.sqrt((s - 3) ** 2 + 24 * s)) / (12 * s)
            xa = aest * (1 - 0.4)
            xb = aest * (1 + 0.4)
            a = optimize.brentq(func, xa, xb, disp=0)

        # The MLE for the scale parameter is just the data mean
        # divided by the shape parameter.
        scale = xbar / a
    else:
        # scale is fixed, shape is free
        # The MLE for the shape parameter `a` is the solution to:
        # sc.digamma(a) - np.log(data).mean() + np.log(fscale) = 0
        c = np.log(data).mean() - np.log(fscale)
        a = _digammainv(c)
        scale = fscale

    return a, floc, scale


# Traceback (RuntimeError)
---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
<ipython-input-86-fb3d43a0acaa> in <module>
13        1.5754, 2.2669, 1.6383, 1.7696, 1.9079, 1.0955, 1.5637, 2.66  ,
14        1.746 , 1.5319, 2.0958,    np.nan])
---> 15 K = stats.exponnorm.fit(x)

/anaconda3/lib/python3.7/site-packages/scipy/stats/_distn_infrastructure.py in fit(self, data, *args, **kwds)
2195                                          'scale' in kwds):
2196             # get distribution specific starting locations
-> 2197             start = self._fitstart(data)
2198             args += start[Narg:-2]
2199         loc = kwds.pop('loc', start[-2])

/anaconda3/lib/python3.7/site-packages/scipy/stats/_distn_infrastructure.py in _fitstart(self, data, args)
2034         if args is None:
2035             args = (1.0,)*self.numargs
-> 2036         loc, scale = self._fit_loc_scale_support(data, *args)
2037         return args + (loc, scale)
2038

/anaconda3/lib/python3.7/site-packages/scipy/stats/_distn_infrastructure.py in _fit_loc_scale_support(self, data, *args)
2287             return (data_b - b) + margin, 1
2288         else:
-> 2289             raise RuntimeError
2290
2291     def fit_loc_scale(self, data, *args):

RuntimeError:

# Fixed code
def fit(self, data, *args, **kwds):
    floc = kwds.get("floc", None)

    if floc is None:
        # loc is not fixed.  Use the default fit method.
        return super(gamma_gen, self).fit(data, *args, **kwds)

    # We already have this value, so just pop it from kwds.
    kwds.pop("floc", None)

    f0 = _get_fixed_fit_value(kwds, ["f0", "fa", "fix_a"])
    fscale = kwds.pop("fscale", None)

    _remove_optimizer_parameters(kwds)

    # Special case: loc is fixed.

    if f0 is not None and fscale is not None:
        # This check is for consistency with `rv_continuous.fit`.
        # Without this check, this function would just return the
        # parameters that were given.
        raise ValueError("All parameters fixed. There is nothing to optimize.")

    # Fixed location is handled by shifting the data.
    data = np.asarray(data)

    if not np.isfinite(data).all():
        raise RuntimeError("The data contains non-finite values.")

    if np.any(data <= floc):
        raise FitDataError("gamma", lower=floc, upper=np.inf)

    if floc != 0:
        # Don't do the subtraction in-place, because `data` might be a
        # view of the input array.
        data = data - floc
    xbar = data.mean()

    # Three cases to handle:
    # * shape and scale both free
    # * shape fixed, scale free
    # * shape free, scale fixed

    if fscale is None:
        # scale is free
        if f0 is not None:
            # shape is fixed
            a = f0
        else:
            # shape and scale are both free.
            # The MLE for the shape parameter `a` is the solution to:
            # np.log(a) - sc.digamma(a) - np.log(xbar) +
            #                             np.log(data.mean) = 0
            s = np.log(xbar) - np.log(data).mean()
            func = lambda a: np.log(a) - sc.digamma(a) - s
            aest = (3 - s + np.sqrt((s - 3) ** 2 + 24 * s)) / (12 * s)
            xa = aest * (1 - 0.4)
            xb = aest * (1 + 0.4)
            a = optimize.brentq(func, xa, xb, disp=0)

        # The MLE for the scale parameter is just the data mean
        # divided by the shape parameter.
        scale = xbar / a
    else:
        # scale is fixed, shape is free
        # The MLE for the shape parameter `a` is the solution to:
        # sc.digamma(a) - np.log(data).mean() + np.log(fscale) = 0
        c = np.log(data).mean() - np.log(fscale)
        a = _digammainv(c)
        scale = fscale

    return a, floc, scale