Factory for function ``labelfunc(expr, is_leaf)``

    It has the following behavior:

    * If ``is_leaf`` is True, return ``leaf_renderer(expr)``.

    * Otherwise,

      - if `expr` is an Expression, return a custom string similar to
        :func:`~qnet.printing.srepr`, but with an ellipsis for ``args``
      - otherwise, return ``fallback(expr)``

def expr_labelfunc(leaf_renderer=str, fallback=str):
    """Factory for function ``labelfunc(expr, is_leaf)``

    It has the following behavior:

    * If ``is_leaf`` is True, return ``leaf_renderer(expr)``.

    * Otherwise,

      - if `expr` is an Expression, return a custom string similar to
        :func:`~qnet.printing.srepr`, but with an ellipsis for ``args``
      - otherwise, return ``fallback(expr)``
    """

    def _labelfunc(expr, is_leaf):
        if is_leaf:
            label = leaf_renderer(expr)
        elif isinstance(expr, Expression):
            if len(expr.kwargs) == 0:
                label = expr.__class__.__name__
            else:
                label = "%s(..., %s)" % (
                    expr.__class__.__name__,
                    ", ".join([
                        "%s=%s" % (key, val)
                        for (key, val) in expr.kwargs.items()]))
        else:
            label = fallback(expr)
        return label

    return _labelfunc