code: def get_index_loc(key, index):
      """
      Get the location of a specific key in an index
  
      Parameters
      ----------
      key : label
          The key for which to find the location if the underlying index is
          a DateIndex or a location if the underlying index is a RangeIndex
          or an Index with an integer dtype.
      index : pd.Index
          The index to search.
  
      Returns
      -------
      loc : int
          The location of the key
      index : pd.Index
          The index including the key; this is a copy of the original index
          unless the index had to be expanded to accommodate `key`.
      index_was_expanded : bool
          Whether or not the index was expanded to accommodate `key`.
  
      Notes
      -----
      If `key` is past the end of of the given index, and the index is either
      an Index with an integral dtype or a date index, this function extends
      the index up to and including key, and then returns the location in the
      new index.
      """
      base_index = index
  
      index = base_index
      date_index = isinstance(base_index, (PeriodIndex, DatetimeIndex))
      int_index = is_int_index(base_index)
      range_index = isinstance(base_index, RangeIndex)
      index_class = type(base_index)
      nobs = len(index)
  
      # Special handling for RangeIndex
      if range_index and isinstance(key, (int, np.integer)):
          # Negative indices (that lie in the Index)
          if key < 0 and -key <= nobs:
              key = nobs + key
          # Out-of-sample (note that we include key itself in the new index)
          elif key > nobs - 1:
              # See gh5835. Remove the except after pandas 0.25 required.
              try:
                  base_index_start = base_index.start
                  base_index_step = base_index.step
              except AttributeError:
                  base_index_start = base_index._start
                  base_index_step = base_index._step
              stop = base_index_start + (key + 1) * base_index_step
              index = RangeIndex(
                  start=base_index_start,
                  stop=stop,
                  step=base_index_step,
              )
  
      # Special handling for NumericIndex
      if (
          not range_index
          and int_index
          and not date_index
          and isinstance(key, (int, np.integer))
      ):
          # Negative indices (that lie in the Index)
          if key < 0 and -key <= nobs:
              key = nobs + key
          # Out-of-sample (note that we include key itself in the new index)
          elif key > base_index[-1]:
              index = Index(np.arange(base_index[0], int(key + 1)))
  
      # Special handling for date indexes
      if date_index:
          # Use index type to choose creation function
          if index_class is DatetimeIndex:
              index_fn = date_range
          else:
              index_fn = period_range
          # Integer key (i.e. already given a location)
          if isinstance(key, (int, np.integer)):
              # Negative indices (that lie in the Index)
              if key < 0 and -key < nobs:
                  key = index[nobs + key]
              # Out-of-sample (note that we include key itself in the new
              # index)
              elif key > len(base_index) - 1:
                  index = index_fn(
                      start=base_index[0],
                      periods=int(key + 1),
                      freq=base_index.freq,
                  )
                  key = index[-1]
              else:
                  key = index[key]
          # Other key types (i.e. string date or some datetime-like object)
          else:
              # Convert the key to the appropriate date-like object
              if index_class is PeriodIndex:
                  date_key = Period(key, freq=base_index.freq)
              else:
                  date_key = Timestamp(key)
  
              # Out-of-sample
              if date_key > base_index[-1]:
                  # First create an index that may not always include `key`
                  index = index_fn(
                      start=base_index[0],
                      end=date_key,
                      freq=base_index.freq,
                  )
  
                  # Now make sure we include `key`
                  if not index[-1] == date_key:
                      index = index_fn(
                          start=base_index[0],
                          periods=len(index) + 1,
                          freq=base_index.freq,
                      )
  
                  # To avoid possible inconsistencies with `get_loc` below,
                  # set the key directly equal to the last index location
                  key = index[-1]
  
      # Get the location
      if date_index:
          # (note that get_loc will throw a KeyError if key is invalid)
          loc = index.get_loc(key)
      elif int_index or range_index:
          # For NumericIndex and RangeIndex, key is assumed to be the location
          # and not an index value (this assumption is required to support
          # RangeIndex)
          try:
              index[key]
          # We want to raise a KeyError in this case, to keep the exception
          # consistent across index types.
          # - Attempting to index with an out-of-bound location (e.g.
          #   index[10] on an index of length 9) will raise an IndexError
          #   (as of Pandas 0.22)
          # - Attemtping to index with a type that cannot be cast to integer
          #   (e.g. a non-numeric string) will raise a ValueError if the
          #   index is RangeIndex (otherwise will raise an IndexError)
          #   (as of Pandas 0.22)
          except (IndexError, ValueError) as e:
              raise KeyError(str(e))
          loc = key
      else:
          loc = index.get_loc(key)
  
      # Check if we now have a modified index
      index_was_expanded = index is not base_index
  
      # Return the index through the end of the loc / slice
      if isinstance(loc, slice):
          end = loc.stop - 1
      else:
          end = loc
  
      return loc, index[: end + 1], index_was_expanded
  
imports: from __future__ import annotations
  from statsmodels.compat.pandas import is_float_index, is_int_index, is_numeric_dtype
  import numbers
  import warnings
  import numpy
  from pandas import DatetimeIndex, Index, Period, PeriodIndex, RangeIndex, Series, Timestamp, date_range, period_range, to_datetime
  from pandas.tseries.frequencies import to_offset
  from statsmodels.base.data import PandasData
  import statsmodels.base.model
  import statsmodels.base.wrapper
  from statsmodels.tools.sm_exceptions import ValueWarning
label_desc: Use image node_id 1 for calling a global function with example usage: get_index_loc(key, index) and returns: loc,  index,  index_was_expanded