Parse scalar operations.

    A scalar operation can one of the following:

     * single value: start_date:12, metric1:>0.9, metric1:>=-0.12
     * negation single value: metric1:~1112, metric1:~<1112 equivalent to metric1:>=1112

    This parser does not allow `|` and `..`.

def parse_scalar_operation(operation: str) -> 'QueryOpSpec':
    """Parse scalar operations.

    A scalar operation can one of the following:

     * single value: start_date:12, metric1:>0.9, metric1:>=-0.12
     * negation single value: metric1:~1112, metric1:~<1112 equivalent to metric1:>=1112

    This parser does not allow `|` and `..`.
    """
    _operation = operation.strip()
    if not _operation:
        raise QueryParserException('Operation is not valid: {}'.format(operation))
    # Check not allowed ops
    if '|' in _operation:
        raise QueryParserException('`|` is not allowed for scalar operations. '
                                   'Operation: {}'.format(operation))
    if '..' in _operation:
        raise QueryParserException('`..` is not allowed for scalar operations. '
                                   'Operation: {}'.format(operation))

    # Check negation
    negation, _operation = parse_negation_operation(_operation)

    # Check comparison operators
    op, _operation = parse_comparison_operation(_operation)
    if not op:
        # Now the operation must be an equality param param
        op = '='

    # Check that params are scalar (int, float)
    try:
        _operation = int(_operation)
    except (ValueError, TypeError):
        try:
            _operation = float(_operation)
        except (ValueError, TypeError):
            raise QueryParserException('Scalar operation requires int or float params, '
                                       'receive {}.'.format(operation))
    return QueryOpSpec(op, negation, _operation)