code: def _ensure_data(values, dtype=None):
      """
      routine to ensure that our data is of the correct
      input dtype for lower-level routines
  
      This will coerce:
      - ints -> int64
      - uint -> uint64
      - bool -> uint64 (TODO this should be uint8)
      - datetimelike -> i8
      - datetime64tz -> i8 (in local tz)
      - categorical -> codes
  
      Parameters
      ----------
      values : array-like
      dtype : pandas_dtype, optional
          coerce to this dtype
  
      Returns
      -------
      (ndarray, pandas_dtype, algo dtype as a string)
  
      """
  
      # we check some simple dtypes first
      try:
          if is_object_dtype(dtype):
              return (
                  ensure_object(np.asarray(values)),
                  "object",
                  "object",
              )
          if is_bool_dtype(values) or is_bool_dtype(dtype):
              # we are actually coercing to uint64
              # until our algos support uint8 directly (see TODO)
              return (
                  np.asarray(values).astype("uint64"),
                  "bool",
                  "uint64",
              )
          elif is_signed_integer_dtype(
              values
          ) or is_signed_integer_dtype(dtype):
              return ensure_int64(values), "int64", "int64"
          elif is_unsigned_integer_dtype(
              values
          ) or is_unsigned_integer_dtype(dtype):
              return ensure_uint64(values), "uint64", "uint64"
          elif is_float_dtype(values) or is_float_dtype(dtype):
              return ensure_float64(values), "float64", "float64"
          elif is_object_dtype(values) and dtype is None:
              return (
                  ensure_object(np.asarray(values)),
                  "object",
                  "object",
              )
          elif is_complex_dtype(values) or is_complex_dtype(dtype):
              # ignore the fact that we are casting to float
              # which discards complex parts
              with catch_warnings():
                  simplefilter("ignore", np.ComplexWarning)
                  values = ensure_float64(values)
              return values, "float64", "float64"
  
      except (TypeError, ValueError, OverflowError):
          # if we are trying to coerce to a dtype
          # and it is incompat this will fall thru to here
          return ensure_object(values), "object", "object"
  
      # datetimelike
      if (
          needs_i8_conversion(values)
          or is_period_dtype(dtype)
          or is_datetime64_any_dtype(dtype)
          or is_timedelta64_dtype(dtype)
      ):
          if is_period_dtype(values) or is_period_dtype(dtype):
              from pandas import PeriodIndex
  
              values = PeriodIndex(values)
              dtype = values.dtype
          elif is_timedelta64_dtype(values) or is_timedelta64_dtype(
              dtype
          ):
              from pandas import TimedeltaIndex
  
              values = TimedeltaIndex(values)
              dtype = values.dtype
          else:
              # Datetime
              from pandas import DatetimeIndex
  
              values = DatetimeIndex(values)
              dtype = values.dtype
  
          return values.asi8, dtype, "int64"
  
      elif is_categorical_dtype(values) and (
          is_categorical_dtype(dtype) or dtype is None
      ):
          values = getattr(values, "values", values)
          values = values.codes
          dtype = "category"
  
          # we are actually coercing to int64
          # until our algos support int* directly (not all do)
          values = ensure_int64(values)
  
          return values, dtype, "int64"
  
      # we have failed, return object
      values = np.asarray(values, dtype=np.object)
      return ensure_object(values), "object", "object"
  
imports: from __future__ import division
  from textwrap import dedent
  from warnings import catch_warnings, simplefilter, warn
  import numpy
  from pandas._libs import algos, hashtable, lib
  from pandas._libs.tslib import iNaT
  from pandas.util._decorators import Appender, Substitution, deprecate_kwarg
  from pandas.core.dtypes.cast import construct_1d_object_array_from_listlike, maybe_promote
  from pandas.core.dtypes.common import ensure_float64, ensure_int64, ensure_object, ensure_platform_int, ensure_uint64, is_array_like, is_bool_dtype, is_categorical_dtype, is_complex_dtype, is_datetime64_any_dtype, is_datetime64tz_dtype, is_datetimelike, is_extension_array_dtype, is_float_dtype, is_integer_dtype, is_interval_dtype, is_list_like, is_numeric_dtype, is_object_dtype, is_period_dtype, is_scalar, is_signed_integer_dtype, is_sparse, is_timedelta64_dtype, is_unsigned_integer_dtype, needs_i8_conversion
  from pandas.core.dtypes.generic import ABCIndex, ABCIndexClass, ABCSeries
  from pandas.core.dtypes.missing import isna, na_value_for_dtype
  from pandas.core import common
label_desc: Use image node_id 1 for calling a global function with example usage: _ensure_data(values, dtype) and returns: ensure_object,  str,  str, values,  dtype,  str, ensure_object,  str,  str, np,  str,  str, ensure_object,  str,  str, values,  dtype,  str, ensure_int64,  str,  str, ensure_uint64,  str,  str, ensure_float64,  str,  str, ensure_object,  str,  str, values,  str,  str