# Buggy code
def handle_formula_data(Y, X, formula, depth=0, missing="drop"):
    """
    Returns endog, exog, and the model specification from arrays and formula

    Parameters
    ----------
    Y : array-like
        Either endog (the LHS) of a model specification or all of the data.
        Y must define __getitem__ for now.
    X : array-like
        Either exog or None. If all the data for the formula is provided in
        Y then you must explicitly set X to None.
    formula : str or patsy.model_desc
        You can pass a handler by import formula_handler and adding a
        key-value pair where the key is the formula object class and
        the value is a function that returns endog, exog, formula object

    Returns
    -------
    endog : array-like
        Should preserve the input type of Y,X
    exog : array-like
        Should preserve the input type of Y,X. Could be None.
    """
    # half ass attempt to handle other formula objects
    if isinstance(formula, tuple(iterkeys(formula_handler))):
        return formula_handler[type(formula)]

    na_action = NAAction(on_NA=missing)

    if X is not None:
        if data_util._is_using_pandas(Y, X):
            result = dmatrices(
                formula, (Y, X), depth, return_type="dataframe", NA_action=na_action
            )
        else:
            result = dmatrices(
                formula, (Y, X), depth, return_type="dataframe", NA_action=na_action
            )
    else:
        if data_util._is_using_pandas(Y, None):
            result = dmatrices(
                formula, Y, depth, return_type="dataframe", NA_action=na_action
            )
        else:
            result = dmatrices(
                formula, Y, depth, return_type="dataframe", NA_action=na_action
            )

    # if missing == 'raise' there's not missing_mask
    missing_mask = getattr(na_action, "missing_mask", None)
    if not np.any(missing_mask):
        missing_mask = None
    return result, missing_mask


# Traceback (AttributeError)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/dist-packages/spyderlib/widgets/externalshell/sitecustomize.py", line 540, in runfile
execfile(filename, namespace)
File "/home/adrian/Desktop/ToDo/statsmodels_debugging/OLS.py", line 34, in <module>
fit.predict( exog=data[:-1] ) # fails
File "/usr/local/lib/python2.7/dist-packages/statsmodels-0.6.1-py2.7-linux-i686.egg/statsmodels/base/model.py", line 739, in predict
exog = dmatrix(self.model.data.orig_exog.design_info.builder,
File "/usr/local/lib/python2.7/dist-packages/pandas/core/generic.py", line 1936, in __getattr__
(type(self).__name__, name))
AttributeError: 'DataFrame' object has no attribute 'design_info'

# Fixed code
def handle_formula_data(Y, X, formula, depth=0, missing="drop"):
    """
    Returns endog, exog, and the model specification from arrays and formula

    Parameters
    ----------
    Y : array-like
        Either endog (the LHS) of a model specification or all of the data.
        Y must define __getitem__ for now.
    X : array-like
        Either exog or None. If all the data for the formula is provided in
        Y then you must explicitly set X to None.
    formula : str or patsy.model_desc
        You can pass a handler by import formula_handler and adding a
        key-value pair where the key is the formula object class and
        the value is a function that returns endog, exog, formula object

    Returns
    -------
    endog : array-like
        Should preserve the input type of Y,X
    exog : array-like
        Should preserve the input type of Y,X. Could be None.
    """
    # half ass attempt to handle other formula objects
    if isinstance(formula, tuple(iterkeys(formula_handler))):
        return formula_handler[type(formula)]

    na_action = NAAction(on_NA=missing)

    if X is not None:
        if data_util._is_using_pandas(Y, X):
            result = dmatrices(
                formula, (Y, X), depth, return_type="dataframe", NA_action=na_action
            )
        else:
            result = dmatrices(
                formula, (Y, X), depth, return_type="dataframe", NA_action=na_action
            )
    else:
        if data_util._is_using_pandas(Y, None):
            result = dmatrices(
                formula, Y, depth, return_type="dataframe", NA_action=na_action
            )
        else:
            result = dmatrices(
                formula, Y, depth, return_type="dataframe", NA_action=na_action
            )

    # if missing == 'raise' there's not missing_mask
    missing_mask = getattr(na_action, "missing_mask", None)
    if not np.any(missing_mask):
        missing_mask = None
    if len(result) > 1:  # have RHS design
        design_info = result[1].design_info  # detach it from DataFrame
    else:
        design_info = None
    # NOTE: is there ever a case where we'd need LHS design_info?
    return result, missing_mask, design_info