Parse a single constraint expression.

    Legal expressions are defined by the regular expression `relation_re`.

    :param e: Expression
    :type e: str
    :return: Tuple of field, operator, and value
    :rtype: tuple

def parse_expr(e):
    """Parse a single constraint expression.

    Legal expressions are defined by the regular expression `relation_re`.

    :param e: Expression
    :type e: str
    :return: Tuple of field, operator, and value
    :rtype: tuple
    """
    m = relation_re.match(e)
    if m is None:
        raise ValueError("error parsing expression '{}'".format(e))
    field, op, val = m.groups()
    # Try different types
    try:
        # Integer
        val_int = int(val)
        val = val_int
    except ValueError:
        try:
            # Float
            val_float = float(val)
            val = val_float
        except ValueError:
            try:
                # Boolean
                val = {'true': True, 'false': False}[val.lower()]
            except KeyError:
                # String
                if re.match(r'".*"|\'.*\'', val):
                    # strip quotes from strings
                    val = val[1:-1]
    return field, op, val