def result_type(*arrays_and_dtypes):
  """Returns the type resulting from applying NumPy type promotion to arguments.

  Args:
    *arrays_and_dtypes: A list of array_like objects or dtypes.

  Returns:
    A numpy dtype.
  """
  def maybe_get_dtype(x):
    # Don't put np.ndarray in this list, because np.result_type looks at the
    # value (not just dtype) of np.ndarray to decide the result type.
    if isinstance(x, (arrays.ndarray, arrays.ShardedNdArray,
                      tf.Tensor, tf.IndexedSlices)):
      return _to_numpy_type(x.dtype)
    elif isinstance(x, tf.DType):
      return _to_numpy_type(x)
    return x
  arrays_and_dtypes = [maybe_get_dtype(x) for x in
                       tf.nest.flatten(arrays_and_dtypes)]
  if not arrays_and_dtypes:
    # If arrays_and_dtypes is an empty list, let numpy decide what the dtype is.
    arrays_and_dtypes = [np.asarray([])]
  return dtypes._result_type(*arrays_and_dtypes)
Returns the type resulting from applying NumPy type promotion to arguments.

  Args:
    *arrays_and_dtypes: A list of array_like objects or dtypes.

  Returns:
    A numpy dtype.
  
trax/tf_numpy/numpy_impl/utils.py