code: def _get_values(
      values: np.ndarray,
      skipna: bool,
      fill_value: Any = None,
      fill_value_typ: str | None = None,
      mask: npt.NDArray[np.bool_] | None = None,
  ) -> tuple[np.ndarray, npt.NDArray[np.bool_] | None]:
      """
      Utility to get the values view, mask, dtype, dtype_max, and fill_value.
  
      If both mask and fill_value/fill_value_typ are not None and skipna is True,
      the values array will be copied.
  
      For input arrays of boolean or integer dtypes, copies will only occur if a
      precomputed mask, a fill_value/fill_value_typ, and skipna=True are
      provided.
  
      Parameters
      ----------
      values : ndarray
          input array to potentially compute mask for
      skipna : bool
          boolean for whether NaNs should be skipped
      fill_value : Any
          value to fill NaNs with
      fill_value_typ : str
          Set to '+inf' or '-inf' to handle dtype-specific infinities
      mask : Optional[np.ndarray[bool]]
          nan-mask if known
  
      Returns
      -------
      values : ndarray
          Potential copy of input value array
      mask : Optional[ndarray[bool]]
          Mask for values, if deemed necessary to compute
      """
      # In _get_values is only called from within nanops, and in all cases
      #  with scalar fill_value.  This guarantee is important for the
      #  np.where call below
  
      mask = _maybe_get_mask(values, skipna, mask)
  
      dtype = values.dtype
  
      datetimelike = False
      if values.dtype.kind in "mM":
          # changing timedelta64/datetime64 to int64 needs to happen after
          #  finding `mask` above
          values = np.asarray(values.view("i8"))
          datetimelike = True
  
      if skipna and (mask is not None):
          # get our fill value (in case we need to provide an alternative
          # dtype for it)
          fill_value = _get_fill_value(
              dtype,
              fill_value=fill_value,
              fill_value_typ=fill_value_typ,
          )
  
          if fill_value is not None:
              if mask.any():
                  if datetimelike or _na_ok_dtype(dtype):
                      values = values.copy()
                      np.putmask(values, mask, fill_value)
                  else:
                      # np.where will promote if needed
                      values = np.where(~mask, values, fill_value)
  
      return values, mask
  
imports: from __future__ import annotations
  import functools
  import itertools
  from typing import Any, Callable, cast
  import warnings
  import numpy
  from pandas._config import get_option
  from pandas._libs import NaT, NaTType, iNaT, lib
  from pandas._typing import ArrayLike, AxisInt, CorrelationMethod, Dtype, DtypeObj, F, Scalar, Shape, npt
  from pandas.compat._optional import import_optional_dependency
  from pandas.util._exceptions import find_stack_level
  from pandas.core.dtypes.common import is_complex, is_float, is_float_dtype, is_integer, is_numeric_dtype, is_object_dtype, needs_i8_conversion, pandas_dtype
  from pandas.core.dtypes.missing import isna, na_value_for_dtype, notna
label_desc: Use image node_id 6 for calling a global function with example usage: _get_values(values, skipna, fill_value, fill_value_typ, mask) and returns: values,  mask