code: def _from_dtype(
      xp: Any,
      api_version: NominalVersion,
      dtype: Union[DataType, str],
      *,
      min_value: Optional[Union[int, float]] = None,
      max_value: Optional[Union[int, float]] = None,
      allow_nan: Optional[bool] = None,
      allow_infinity: Optional[bool] = None,
      allow_subnormal: Optional[bool] = None,
      exclude_min: Optional[bool] = None,
      exclude_max: Optional[bool] = None,
  ) -> st.SearchStrategy[Union[bool, int, float, complex]]:
      """Return a strategy for any value of the given dtype.
  
      Values generated are of the Python scalar which is
      :xp-ref:`promotable <type_promotion.html>` to ``dtype``, where the values do
      not exceed its bounds.
  
      * ``dtype`` may be a dtype object or the string name of a
        :xp-ref:`valid dtype <data_types.html>`.
  
      Compatible ``**kwargs`` are passed to the inferred strategy function for
      integers and floats.  This allows you to customise the min and max values,
      and exclude non-finite numbers. This is particularly useful when kwargs are
      passed through from :func:`arrays()`, as it seamlessly handles the ``width``
      or other representable bounds for you.
      """
      # TODO: for next released xp version, add note for complex dtype support
      check_xp_attributes(xp, ["iinfo", "finfo"])
  
      if isinstance(dtype, str):
          dtype = dtype_from_name(xp, dtype)
      builtin = find_castable_builtin_for_dtype(xp, api_version, dtype)
  
      def check_valid_minmax(prefix, val, info_obj):
          name = f"{prefix}_value"
          check_valid_bound(val, name)
          check_argument(
              val >= info_obj.min,
              f"dtype={dtype} requires {name}={val} to be at least {info_obj.min}",
          )
          check_argument(
              val <= info_obj.max,
              f"dtype={dtype} requires {name}={val} to be at most {info_obj.max}",
          )
  
      if builtin is bool:
          return st.booleans()
      elif builtin is int:
          iinfo = xp.iinfo(dtype)
          if min_value is None:
              min_value = iinfo.min
          if max_value is None:
              max_value = iinfo.max
          check_valid_integer(min_value, "min_value")
          check_valid_integer(max_value, "max_value")
          assert isinstance(min_value, int)
          assert isinstance(max_value, int)
          check_valid_minmax("min", min_value, iinfo)
          check_valid_minmax("max", max_value, iinfo)
          check_valid_interval(
              min_value, max_value, "min_value", "max_value"
          )
          return st.integers(min_value=min_value, max_value=max_value)
      elif builtin is float:
          finfo = xp.finfo(dtype)
          kw = {}
  
          # Whilst we know the boundary values of float dtypes from finfo, we do
          # not assign them to the floats() strategy by default - passing min/max
          # values will modify test case reduction behaviour so that simple bugs
          # may become harder for users to identify. We plan to improve floats()
          # behaviour in https://github.com/HypothesisWorks/hypothesis/issues/2907.
          # Setting width should manage boundary values for us anyway.
          if min_value is not None:
              check_valid_bound(min_value, "min_value")
              assert isinstance(min_value, Real)
              check_valid_minmax("min", min_value, finfo)
              kw["min_value"] = min_value
          if max_value is not None:
              check_valid_bound(max_value, "max_value")
              assert isinstance(max_value, Real)
              check_valid_minmax("max", max_value, finfo)
              if min_value is not None:
                  check_valid_interval(
                      min_value, max_value, "min_value", "max_value"
                  )
              kw["max_value"] = max_value
  
          # We infer whether an array module will flush subnormals to zero, as may
          # be the case when libraries are built with compiler options that
          # violate IEEE-754 (e.g. -ffast-math and -ftz=true). Note we do this for
          # the specific dtype, as compilers may end up flushing subnormals for
          # one float but supporting subnormals for the other.
          #
          # By default, floats() will generate subnormals if they are in the
          # inferred values range. If we have detected that xp flushes to zero for
          # the passed dtype, we ensure from_dtype() will not generate subnormals
          # by default.
          if allow_subnormal is not None:
              kw["allow_subnormal"] = allow_subnormal
          else:
              subnormal = next_down(
                  finfo.smallest_normal, width=finfo.bits
              )
              ftz = bool(xp.asarray(subnormal, dtype=dtype) == 0)
              if ftz:
                  kw["allow_subnormal"] = False
  
          if allow_nan is not None:
              kw["allow_nan"] = allow_nan
          if allow_infinity is not None:
              kw["allow_infinity"] = allow_infinity
          if exclude_min is not None:
              kw["exclude_min"] = exclude_min
          if exclude_max is not None:
              kw["exclude_max"] = exclude_max
  
          return st.floats(width=finfo.bits, **kw)
      else:
          finfo = xp.finfo(dtype)
          # See above comment on FTZ inference. We explicitly infer with a
          # complex array, in case complex arrays have different FTZ behaviour
          # than arrays of the respective composite float.
          if allow_subnormal is None:
              subnormal = next_down(
                  finfo.smallest_normal, width=finfo.bits
              )
              x = xp.asarray(complex(subnormal, subnormal), dtype=dtype)
              builtin_x = complex(x)
              allow_subnormal = (
                  builtin_x.real != 0 and builtin_x.imag != 0
              )
          return st.complex_numbers(
              allow_nan=allow_nan,
              allow_infinity=allow_infinity,
              allow_subnormal=allow_subnormal,
              width=finfo.bits * 2,
          )
  
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 6 for calling a global function with example usage: _from_dtype(xp, api_version, dtype) and returns: st, st, st, st