code: def find_castable_builtin_for_dtype(
      xp: Any, api_version: NominalVersion, dtype: DataType
  ) -> Type[Union[bool, int, float, complex]]:
      """Returns builtin type which can have values that are castable to the given
      dtype, according to :xp-ref:`type promotion rules <type_promotion.html>`.
  
      For floating dtypes we always return ``float``, even though ``int`` is also castable.
      """
      stubs = []
  
      try:
          bool_dtype = xp.bool
          if dtype == bool_dtype:
              return bool
      except AttributeError:
          stubs.append("bool")
  
      int_dtypes, int_stubs = partition_attributes_and_stubs(
          xp, ALL_INT_NAMES
      )
      if dtype in int_dtypes:
          return int
  
      float_dtypes, float_stubs = partition_attributes_and_stubs(
          xp, FLOAT_NAMES
      )
      # None equals NumPy's xp.float64 object, so we specifically skip it here to
      # ensure that InvalidArgument is still raised. xp.float64 is in fact an
      # alias of np.dtype('float64'), and its equality with None is meant to be
      # deprecated at some point. See https://github.com/numpy/numpy/issues/18434
      if dtype is not None and dtype in float_dtypes:
          return float
  
      stubs.extend(int_stubs)
      stubs.extend(float_stubs)
  
      if api_version > "2021.12":
          (
              complex_dtypes,
              complex_stubs,
          ) = partition_attributes_and_stubs(xp, COMPLEX_NAMES)
          if dtype in complex_dtypes:
              return complex
          stubs.extend(complex_stubs)
  
      if len(stubs) > 0:
          warn_on_missing_dtypes(xp, stubs)
      raise InvalidArgument(
          f"dtype={dtype} not recognised in {xp.__name__}"
      )
  
imports: import math
  import sys
  from numbers import Real
  from types import SimpleNamespace
  from typing import TYPE_CHECKING, Any, Iterable, Iterator, List, Literal, Mapping, NamedTuple, Optional, Sequence, Tuple, Type, TypeVar, Union, get_args
  from warnings import warn
  from weakref import WeakValueDictionary
  from hypothesis import strategies
  from hypothesis.errors import HypothesisWarning, InvalidArgument
  from hypothesis.extra._array_helpers import NDIM_MAX, BasicIndex, BasicIndexStrategy, BroadcastableShapes, Shape, array_shapes, broadcastable_shapes, check_argument, check_valid_dims, mutually_broadcastable_shapes, order_check, valid_tuple_axes
  from hypothesis.internal.conjecture import utils
  from hypothesis.internal.coverage import check_function
  from hypothesis.internal.floats import next_down
  from hypothesis.internal.reflection import proxies
  from hypothesis.internal.validation import check_type, check_valid_bound, check_valid_integer, check_valid_interval
  from hypothesis.strategies._internal.strategies import check_strategy
  from hypothesis.strategies._internal.utils import defines_strategy
label_desc: Use image node_id 4 for calling a global function with example usage: find_castable_builtin_for_dtype(xp, api_version, dtype) and returns: int, float, bool, complex