code: def check_X_y(
      X: Union[np.generic, np.ndarray, pd.DataFrame],
      y: Union[np.generic, np.ndarray, pd.Series, List],
      multi_output: bool = False,
      y_numeric: bool = False,
  ) -> Tuple[pd.DataFrame, pd.Series]:
      """
      Ensures X and y are compatible pandas DataFrame and Series. If both are pandas
      objects, checks that their indexes match. If any is a numpy array, converts to
      pandas object with compatible index.
  
      This transformer ensures that we can concatenate X and y using `pandas.concat`,
      functionality needed in the encoders.
  
      Parameters
      ----------
      X: Pandas DataFrame or numpy ndarray
          The input to check and copy or transform.
  
      y: pd.Series, np.array, list
          The input to check and copy or transform.
  
      multi_output : bool, default=False
          Whether to allow 2D y (array). If false, y will be
          validated as a vector. y cannot have np.nan or np.inf values if
          multi_output=True.
  
      y_numeric : bool, default=False
          Whether to ensure that y has a numeric type. If dtype of y is object,
          it is converted to float64. Should only be used for regression
          algorithms.
  
      Raises
      ------
      ValueError: if X and y are pandas objects with inconsistent indexes.
      TypeError: if X is sparse matrix, empty dataframe or not a dataframe.
      TypeError: if y can't be parsed as pandas Series.
  
      Returns
      -------
      X: Pandas DataFrame
      y: Pandas Series
      """
  
      def _check_X_y(X, y):
          X = check_X(X)
          y = check_y(y, multi_output=multi_output, y_numeric=y_numeric)
          check_consistent_length(X, y)
          return X, y
  
      # case 1: both are pandas objects
      if isinstance(X, pd.DataFrame) and isinstance(y, pd.Series):
          X, y = _check_X_y(X, y)
          # Check that their indexes match.
          if X.index.equals(y.index) is False:
              raise ValueError("The indexes of X and y do not match.")
  
      # case 2: X is dataframe and y is something else
      if isinstance(X, pd.DataFrame) and not isinstance(y, pd.Series):
          X, y = _check_X_y(X, y)
          y.index = X.index
  
      # case 3: X is not a dataframe and y is a series
      elif not isinstance(X, pd.DataFrame) and isinstance(y, pd.Series):
          X, y = _check_X_y(X, y)
          X.index = y.index
  
      # all other cases
      else:
          X, y = _check_X_y(X, y)
  
      return X, y
  
file_path: feature_engine/feature_engine/dataframe_checks.py
imports: from typing import List, Tuple, Union
  import numpy
  import pandas
  from scipy.sparse import issparse
  from sklearn.utils.validation import _check_y, check_consistent_length
label_desc: Use image node_id 3 for calling a global function with example usage: check_X_y(X, y, multi_output, y_numeric) and returns: X,  y, X,  y