code: def promote_types(a: DTypeLike, b: DTypeLike) -> DType:
      """Returns the type to which a binary operation should cast its arguments.
  
      For details of JAX's type promotion semantics, see :ref:`type-promotion`.
  
      Args:
        a: a :class:`numpy.dtype` or a dtype specifier.
        b: a :class:`numpy.dtype` or a dtype specifier.
  
      Returns:
        A :class:`numpy.dtype` object.
      """
      # Note: we deliberately avoid `if a in _weak_types` here because we want to check
      # object identity, not object equality, due to the behavior of np.dtype.__eq__
      a_tp = cast(
          JAXType,
          a if any(a is t for t in _weak_types) else np.dtype(a),
      )
      b_tp = cast(
          JAXType,
          b if any(b is t for t in _weak_types) else np.dtype(b),
      )
      return np.dtype(
          _least_upper_bound(
              config.numpy_dtype_promotion.value, a_tp, b_tp
          )
      )
  
imports: from __future__ import annotations
  import abc
  import builtins
  import functools
  from typing import cast, overload, Any, Literal, Union
  import warnings
  import ml_dtypes
  import numpy
  from jax._src import config
  from jax._src.typing import DType, DTypeLike
  from jax._src.util import set_module
  from jax._src import traceback_util
label_desc: Use image node_id 19 for calling a global function with example usage: promote_types(a, b) and returns: np