def str_to_size(size_str):
    """
    Receives a human size (i.e. 10GB) and converts to an integer size in
    mebibytes.

    Args:
        size_str (str): human size to be converted to integer

    Returns:
        int: formatted size in mebibytes

    Raises:
        ValueError: in case size provided in invalid
    """
    if size_str is None:
        return None

    # no unit: assume mebibytes as default and convert directly
    if size_str.isnumeric():
        return int(size_str)

    size_str = size_str.upper()

    # check if size is non-negative number
    if size_str.startswith('-'):
        raise ValueError(
            'Invalid size format: {}'.format(size_str)) from None

    # decimal units are converted to bytes and then to mebibytes
    dec_units = ('KB', 'MB', 'GB', 'TB')
    for index, unit in enumerate(dec_units):
        # unit used is different: try next
        if not size_str.endswith(unit):
            continue
        try:
            size_int = int(size_str[:-2]) * pow(1000, index+1)
        except ValueError:
            raise ValueError(
                'Invalid size format: {}'.format(size_str)) from None
        # result is returned in mebibytes
        return int(size_int / pow(1024, 2))

    # binary units are just divided/multipled by powers of 2
    bin_units = ('KIB', 'MIB', 'GIB', 'TIB')
    for index, unit in enumerate(bin_units):
        # unit used is different: try next
        if not size_str.endswith(unit):
            continue
        try:
            size_int = int(int(size_str[:-3]) * pow(1024, index-1))
        except ValueError:
            raise ValueError(
                'Invalid size format: {}'.format(size_str)) from None
        return size_int

    raise ValueError(
        'Invalid size format: {}'.format(size_str)) from None