def METHOD_NAME(sprint_opts, log_posteriors, seq_lengths, seq_tags):
    """
    :param dict[str] sprint_opts:
    :param tf.Tensor log_posteriors: 3d (time,batch,label)
    :param tf.Tensor seq_lengths: 1d (batch,)
    :param tf.Tensor seq_tags: 1d (batch,), seq names
    :return: (loss, error_signal), error_signal has the same shape as posteriors. loss is a 1d-array (batch).
    :rtype: (tf.Tensor, tf.Tensor)
    """
    def py_wrap_get_sprint_loss_and_error_signal(py_log_posteriors, py_seq_lengths, py_seq_tags):
        """
        :param numpy.ndarray py_log_posteriors: 3d (time,batch,label)
        :param numpy.ndarray py_seq_lengths: 1d (batch)
        :param list[str] py_seq_tags:
        :return: (loss, error_signal), error_signal has the same shape as posteriors. loss is a 1d-array (batch).
        :rtype: (numpy.ndarray, numpy.ndarray)
        """
        try:
            return py_get_sprint_loss_and_error_signal(
                sprint_opts=sprint_opts,
                log_posteriors=py_log_posteriors,
                seq_lengths=py_seq_lengths,
                seq_tags=py_seq_tags,
            )
        except Exception:
            print("Exception in py_wrap_get_sprint_loss_and_error_signal:")
            import sys
            sys.excepthook(*sys.exc_info())
            raise
    log_posteriors.set_shape((None, None, None))  # (time,batch,label)
    seq_lengths.set_shape((None,))  # (batch,)
    seq_tags.set_shape((None,))  # (batch,)
    loss, error_signal = tf_compat.v1.py_func(
        py_wrap_get_sprint_loss_and_error_signal,
        [log_posteriors, seq_lengths, seq_tags],
        [tf.float32, tf.float32],
        name="get_sprint_loss_and_error_signal",
    )
    assert isinstance(loss, tf.Tensor)
    assert isinstance(error_signal, tf.Tensor)
    loss.set_shape((None,))  # (batch,)
    error_signal.set_shape(log_posteriors.get_shape())  # (time,batch,label)
    return loss, error_signal