# Buggy code
def _build_fstring(self, pos, ustring, format_args):
    # Issues formatting warnings instead of errors since we really only catch a few errors by accident.
    args = iter(format_args)
    substrings = []
    can_be_optimised = True
    for s in re.split(self._parse_string_format_regex, ustring):
        if not s:
            continue
        if s == "%%":
            substrings.append(
                ExprNodes.UnicodeNode(
                    pos, value=EncodedString("%"), constant_result="%"
                )
            )
            continue
        if s[0] != "%":
            if s[-1] == "%":
                warning(pos, "Incomplete format: '...%s'" % s[-3:], level=1)
                can_be_optimised = False
            substrings.append(
                ExprNodes.UnicodeNode(pos, value=EncodedString(s), constant_result=s)
            )
            continue
        format_type = s[-1]
        try:
            arg = next(args)
        except StopIteration:
            warning(pos, "Too few arguments for format placeholders", level=1)
            can_be_optimised = False
            break
        if arg.is_starred:
            can_be_optimised = False
            break
        if format_type in "asrfdoxX":
            format_spec = s[1:]
            conversion_char = None
            if format_type in "doxX" and "." in format_spec:
                # Precision is not allowed for integers in format(), but ok in %-formatting.
                can_be_optimised = False
            elif format_type in "ars":
                format_spec = format_spec[:-1]
                conversion_char = format_type
            elif format_type == "d":
                # '%d' formatting supports float, but '{obj:d}' does not => convert to int first.
                conversion_char = "d"
            substrings.append(
                ExprNodes.FormattedValueNode(
                    arg.pos,
                    value=arg,
                    conversion_char=conversion_char,
                    format_spec=ExprNodes.UnicodeNode(
                        pos,
                        value=EncodedString(format_spec),
                        constant_result=format_spec,
                    )
                    if format_spec
                    else None,
                )
            )
        else:
            # keep it simple for now ...
            can_be_optimised = False
            break

    if not can_be_optimised:
        # Print all warnings we can find before finally giving up here.
        return None

    try:
        next(args)
    except StopIteration:
        pass
    else:
        warning(pos, "Too many arguments for format placeholders", level=1)
        return None

    node = ExprNodes.JoinedStrNode(pos, values=substrings)
    return self.visit_JoinedStrNode(node)


# Traceback (ValueError)
$ cython --embed -3 foo.py &amp;&amp; gcc foo.c -lpython3.8 -o foo
$ ./foo
str: '        '
Traceback (most recent call last):
File "foo.py", line 2, in init foo
print("str: '%08s'" % ("",))
ValueError: '=' alignment not allowed in string format specifier

# Fixed code
def _build_fstring(self, pos, ustring, format_args):
    # Issues formatting warnings instead of errors since we really only catch a few errors by accident.
    args = iter(format_args)
    substrings = []
    can_be_optimised = True
    for s in re.split(self._parse_string_format_regex, ustring):
        if not s:
            continue
        if s == "%%":
            substrings.append(
                ExprNodes.UnicodeNode(
                    pos, value=EncodedString("%"), constant_result="%"
                )
            )
            continue
        if s[0] != "%":
            if s[-1] == "%":
                warning(pos, "Incomplete format: '...%s'" % s[-3:], level=1)
                can_be_optimised = False
            substrings.append(
                ExprNodes.UnicodeNode(pos, value=EncodedString(s), constant_result=s)
            )
            continue
        format_type = s[-1]
        try:
            arg = next(args)
        except StopIteration:
            warning(pos, "Too few arguments for format placeholders", level=1)
            can_be_optimised = False
            break
        if arg.is_starred:
            can_be_optimised = False
            break
        if format_type in "asrfdoxX":
            format_spec = s[1:]
            conversion_char = None
            if format_type in "doxX" and "." in format_spec:
                # Precision is not allowed for integers in format(), but ok in %-formatting.
                can_be_optimised = False
            elif format_type in "ars":
                format_spec = format_spec[:-1]
                conversion_char = format_type
                if format_spec.startswith("0"):
                    format_spec = (
                        ">" + format_spec[1:]
                    )  # right-alignment '%05s' spells '{:>5}'
            elif format_type == "d":
                # '%d' formatting supports float, but '{obj:d}' does not => convert to int first.
                conversion_char = "d"

            if format_spec.startswith("-"):
                format_spec = (
                    "<" + format_spec[1:]
                )  # left-alignment '%-5s' spells '{:<5}'

            substrings.append(
                ExprNodes.FormattedValueNode(
                    arg.pos,
                    value=arg,
                    conversion_char=conversion_char,
                    format_spec=ExprNodes.UnicodeNode(
                        pos,
                        value=EncodedString(format_spec),
                        constant_result=format_spec,
                    )
                    if format_spec
                    else None,
                )
            )
        else:
            # keep it simple for now ...
            can_be_optimised = False
            break

    if not can_be_optimised:
        # Print all warnings we can find before finally giving up here.
        return None

    try:
        next(args)
    except StopIteration:
        pass
    else:
        warning(pos, "Too many arguments for format placeholders", level=1)
        return None

    node = ExprNodes.JoinedStrNode(pos, values=substrings)
    return self.visit_JoinedStrNode(node)