def parse_definition_expr(expr, default_value=None):
    """
    Parses a definition expression and returns a key-value pair
    as a tuple.

    Each definition expression should be in one of these two formats:

        * <variable>=<value>
        * <variable>

    :param expr:
        String expression to be parsed.
    :param default_value:
        (Default None) When a definition is encountered that has no value, this
        will be used as its value.
    :return:
        A (define, value) tuple

        or raises a ``ValueError`` if an invalid
        definition expression is provided.

        or raises ``AttributeError`` if None is provided for ``expr``.

    Usage:

        >>> parse_definition_expr('DEBUG=1')
        ('DEBUG', 1)
        >>> parse_definition_expr('FOOBAR=0x40')
        ('FOOBAR', 64)
        >>> parse_definition_expr('FOOBAR=whatever')
        ('FOOBAR', 'whatever')
        >>> parse_definition_expr('FOOBAR=false')
        ('FOOBAR', False)
        >>> parse_definition_expr('FOOBAR=TRUE')
        ('FOOBAR', True)
        >>> parse_definition_expr('FOOBAR', default_value=None)
        ('FOOBAR', None)
        >>> parse_definition_expr('FOOBAR', default_value=1)
        ('FOOBAR', 1)
        >>> parse_definition_expr('FOOBAR=ah=3')
        ('FOOBAR', 'ah=3')
        >>> parse_definition_expr(' FOOBAR=ah=3 ')
        ('FOOBAR', 'ah=3 ')
        >>> parse_definition_expr(' FOOBAR =ah=3 ')
        ('FOOBAR', 'ah=3 ')
        >>> parse_definition_expr(' FOOBAR = ah=3 ')
        ('FOOBAR', ' ah=3 ')
        >>> parse_definition_expr(" ")
        Traceback (most recent call last):
            ...
        ValueError: Invalid definition symbol ` `
        >>> parse_definition_expr(None)
        Traceback (most recent call last):
            ...
        AttributeError: 'NoneType' object has no attribute 'split'
    """
    try:
        define, value = expr.split('=', 1)
        try:
            value = parse_number_token(value)
        except ValueError:
            value = parse_bool_token(value)
    except ValueError:
        if expr:
            define, value = expr, default_value
        else:
            raise ValueError("Invalid definition expression `%s`" % str(expr))
    d = define.strip()
    if d:
        return d, value
    else:
        raise ValueError("Invalid definition symbol `%s`" % str(define))
Parses a definition expression and returns a key-value pair
    as a tuple.

    Each definition expression should be in one of these two formats:

        * <variable>=<value>
        * <variable>

    :param expr:
        String expression to be parsed.
    :param default_value:
        (Default None) When a definition is encountered that has no value, this
        will be used as its value.
    :return:
        A (define, value) tuple

        or raises a ``ValueError`` if an invalid
        definition expression is provided.

        or raises ``AttributeError`` if None is provided for ``expr``.

    Usage:

        >>> parse_definition_expr('DEBUG=1')
        ('DEBUG', 1)
        >>> parse_definition_expr('FOOBAR=0x40')
        ('FOOBAR', 64)
        >>> parse_definition_expr('FOOBAR=whatever')
        ('FOOBAR', 'whatever')
        >>> parse_definition_expr('FOOBAR=false')
        ('FOOBAR', False)
        >>> parse_definition_expr('FOOBAR=TRUE')
        ('FOOBAR', True)
        >>> parse_definition_expr('FOOBAR', default_value=None)
        ('FOOBAR', None)
        >>> parse_definition_expr('FOOBAR', default_value=1)
        ('FOOBAR', 1)
        >>> parse_definition_expr('FOOBAR=ah=3')
        ('FOOBAR', 'ah=3')
        >>> parse_definition_expr(' FOOBAR=ah=3 ')
        ('FOOBAR', 'ah=3 ')
        >>> parse_definition_expr(' FOOBAR =ah=3 ')
        ('FOOBAR', 'ah=3 ')
        >>> parse_definition_expr(' FOOBAR = ah=3 ')
        ('FOOBAR', ' ah=3 ')
        >>> parse_definition_expr(" ")
        Traceback (most recent call last):
            ...
        ValueError: Invalid definition symbol ` `
        >>> parse_definition_expr(None)
        Traceback (most recent call last):
            ...
        AttributeError: 'NoneType' object has no attribute 'split'