"""
Format expression type checker.

This file is conceptually part of ExpressionChecker and TypeChecker. Main functionality
is located in StringFormatterChecker.check_str_format_call() for '{}'.format(), and in
StringFormatterChecker.check_str_interpolation() for printf-style % interpolation.

Note that although at runtime format strings are parsed using custom parsers,
here we use a regexp-based approach. This way we 99% match runtime behaviour while keeping
implementation simple.
"""

from __future__ import annotations

import re
from typing import TYPE_CHECKING, Callable, Dict, Match, Pattern, Tuple, Union, cast
from typing_extensions import Final, TypeAlias as _TypeAlias

import mypy.errorcodes as codes
from mypy.errors import Errors
from mypy.nodes import (
    ARG_NAMED,
    ARG_POS,
    ARG_STAR,
    ARG_STAR2,
    BytesExpr,
    CallExpr,
    Context,
    DictExpr,
    Expression,
    ExpressionStmt,
    IndexExpr,
    IntExpr,
    MemberExpr,
    MypyFile,
    NameExpr,
    Node,
    StarExpr,
    StrExpr,
    TempNode,
    TupleExpr,
)
from mypy.types import (
    AnyType,
    Instance,
    LiteralType,
    TupleType,
    Type,
    TypeOfAny,
    TypeVarType,
    UnionType,
    get_proper_type,
    get_proper_types,
)

if TYPE_CHECKING:
    # break import cycle only needed for mypy
    import mypy.checker
    import mypy.checkexpr

from mypy import message_registry
from mypy.maptype import map_instance_to_supertype
from mypy.messages import MessageBuilder
from mypy.parse import parse
from mypy.subtypes import is_subtype
from mypy.typeops import custom_special_method

FormatStringExpr: _TypeAlias = Union[StrExpr, BytesExpr]
Checkers: _TypeAlias = Tuple[Callable[[Expression], None], Callable[[Type], bool]]
MatchMap: _TypeAlias = Dict[Tuple[int, int], Match[str]]  # span -> match


def compile_format_re() -> Pattern[str]:
    """Construct regexp to match format conversion specifiers in % interpolation.

    See https://docs.python.org/3/library/stdtypes.html#printf-style-string-formatting
    The regexp is intentionally a bit wider to report better errors.
    """
    key_re = r"(\((?P<key>[^)]*)\))?"  # (optional) parenthesised sequence of characters.
    flags_re = r"(?P<flags>[#0\-+ ]*)"  # (optional) sequence of flags.
    width_re = r"(?P<width>[1-9][0-9]*|\*)?"  # (optional) minimum field width (* or numbers).
    precision_re = r"(?:\.(?P<precision>\*|[0-9]+)?)?"  # (optional) . followed by * of numbers.
    length_mod_re = r"[hlL]?"  # (optional) length modifier (unused).
    type_re = r"(?P<type>.)?"  # conversion type.
    format_re = "%" + key_re + flags_re + width_re + precision_re + length_mod_re + type_re
    return re.compile(format_re)


def compile_new_format_re(custom_spec: bool) -> Pattern[str]:
    """Construct regexps to match format conversion specifiers in str.format() calls.

    See After https://docs.python.org/3/library/string.html#formatspec for
    specifications. The regexps are intentionally wider, to report better errors,
    instead of just not matching.
    """

    # Field (optional) is an integer/identifier possibly followed by several .attr and [index].
    field = r"(?P<field>(?P<key>[^.[!:]*)([^:!]+)?)"

    # Conversion (optional) is ! followed by one of letters for forced repr(), str(), or ascii().
    conversion = r"(?P<conversion>![^:])?"

    # Format specification (optional) follows its own mini-language:
    if not custom_spec:
        # Fill and align is valid for all builtin types.
        fill_align = r"(?P<fill_align>.?[<>=^])?"
        # Number formatting options are only valid for int, float, complex, and Decimal,
        # except if only width is given (it is valid for all types).
        # This contains sign, flags (sign, # and/or 0), width, grouping (_ or ,) and precision.
        num_spec = r"(?P<flags>[+\- ]?#?0?)(?P<width>\d+)?[_,]?(?P<precision>\.\d+)?"
        # The last element is type.
        conv_type = r"(?P<type>.)?"  # only some are supported, but we want to give a better error
        format_spec = r"(?P<format_spec>:" + fill_align + num_spec + conv_type + r")?"
    else:
        # Custom types can define their own form_spec using __format__().
        format_spec = r"(?P<format_spec>:.*)?"

    return re.compile(field + conversion + format_spec)


FORMAT_RE: Final = compile_format_re()
FORMAT_RE_NEW: Final = compile_new_format_re(False)
FORMAT_RE_NEW_CUSTOM: Final = compile_new_format_re(True)
DUMMY_FIELD_NAME: Final = "__dummy_name__"

# Types that require either int or float.
NUMERIC_TYPES_OLD: Final = {"d", "i", "o", "u", "x", "X", "e", "E", "f", "F", "g", "G"}
NUMERIC_TYPES_NEW: Final = {"b", "d", "o", "e", "E", "f", "F", "g", "G", "n", "x", "X", "%"}

# These types accept _only_ int.
REQUIRE_INT_OLD: Final = {"o", "x", "X"}
REQUIRE_INT_NEW: Final = {"b", "d", "o", "x", "X"}

# These types fall back to SupportsFloat with % (other fall back to SupportsInt)
FLOAT_TYPES: Final = {"e", "E", "f", "F", "g", "G"}


class ConversionSpecifier:
    def __init__(
        self, match: Match[str], start_pos: int = -1, non_standard_format_spec: bool = False
    ) -> None:
        self.whole_seq = match.group()
        self.start_pos = start_pos

        m_dict = match.groupdict()
        self.key = m_dict.get("key")

        # Replace unmatched optional groups with empty matches (for convenience).
        self.conv_type = m_dict.get("type", "")
        self.flags = m_dict.get("flags", "")
        self.width = m_dict.get("width", "")
        self.precision = m_dict.get("precision", "")

        # Used only for str.format() calls (it may be custom for types with __format__()).
        self.format_spec = m_dict.get("format_spec")
        self.non_standard_format_spec = non_standard_format_spec
        # Used only for str.format() calls.
        self.conversion = m_dict.get("conversion")
        # Full formatted expression (i.e. key plus following attributes and/or indexes).
        # Used only for str.format() calls.
        self.field = m_dict.get("field")

    def has_key(self) -> bool:
        return self.key is not None

    def has_star(self) -> bool:
        return self.width == "*" or self.precision == "*"


def parse_conversion_specifiers(format_str: str) -> list[ConversionSpecifier]:
    """Parse c-printf-style format string into list of conversion specifiers."""
    specifiers: list[ConversionSpecifier] = []
    for m in re.finditer(FORMAT_RE, format_str):
        specifiers.append(ConversionSpecifier(m, start_pos=m.start()))
    return specifiers


def parse_format_value(
    format_value: str, ctx: Context, msg: MessageBuilder, nested: bool = False
) -> list[ConversionSpecifier] | None:
    """Parse format string into list of conversion specifiers.

    The specifiers may be nested (two levels maximum), in this case they are ordered as
    '{0:{1}}, {2:{3}{4}}'. Return None in case of an error.
    """
    top_targets = find_non_escaped_targets(format_value, ctx, msg)
    if top_targets is None:
        return None

    result: list[ConversionSpecifier] = []
    for target, start_pos in top_targets:
        match = FORMAT_RE_NEW.fullmatch(target)
        if match:
            conv_spec = ConversionSpecifier(match, start_pos=start_pos)
        else:
            custom_match = FORMAT_RE_NEW_CUSTOM.fullmatch(target)
            if custom_match:
                conv_spec = ConversionSpecifier(
                    custom_match, start_pos=start_pos, non_standard_format_spec=True
                )
            else:
                msg.fail(
                    "Invalid conversion specifier in format string",
                    ctx,
                    code=codes.STRING_FORMATTING,
                )
                return None

        if conv_spec.key and ("{" in conv_spec.key or "}" in conv_spec.key):
            msg.fail("Conversion value must not contain { or }", ctx, code=codes.STRING_FORMATTING)
            return None
        result.append(conv_spec)

        # Parse nested conversions that are allowed in format specifier.
        if (
            conv_spec.format_spec
            and conv_spec.non_standard_format_spec
            and ("{" in conv_spec.format_spec or "}" in conv_spec.format_spec)
        ):
            if nested:
                msg.fail(
                    "Formatting nesting must be at most two levels deep",
                    ctx,
                    code=codes.STRING_FORMATTING,
                )
                return None
            sub_conv_specs = parse_format_value(conv_spec.format_spec, ctx, msg, nested=True)
            if sub_conv_specs is None:
                return None
            result.extend(sub_conv_specs)
    return result


def find_non_escaped_targets(
    format_value: str, ctx: Context, msg: MessageBuilder
) -> list[tuple[str, int]] | None:
    """Return list of raw (un-parsed) format specifiers in format string.

    Format specifiers don't include enclosing braces. We don't use regexp for
    this because they don't work well with nested/repeated patterns
    (both greedy and non-greedy), and these are heavily used internally for
    representation of f-strings.

    Return None in case of an error.
    """
    result = []
    next_spec = ""
    pos = 0
    nesting = 0
    while pos < len(format_value):
        c = format_value[pos]
        if not nesting:
            # Skip any paired '{{' and '}}', enter nesting on '{', report error on '}'.
            if c == "{":
                if pos < len(format_value) - 1 and format_value[pos + 1] == "{":
                    pos += 1
                else:
                    nesting = 1
            if c == "}":
                if pos < len(format_value) - 1 and format_value[pos + 1] == "}":
                    pos += 1
                else:
                    msg.fail(
                        "Invalid conversion specifier in format string: unexpected }",
                        ctx,
                        code=codes.STRING_FORMATTING,
                    )
                    return None
        else:
            # Adjust nesting level, then either continue adding chars or move on.
            if c == "{":
                nesting += 1
            if c == "}":
                nesting -= 1
            if nesting:
                next_spec += c
            else:
                result.append((next_spec, pos - len(next_spec)))
                next_spec = ""
        pos += 1
    if nesting:
        msg.fail(
            "Invalid conversion specifier in format string: unmatched {",
            ctx,
            code=codes.STRING_FORMATTING,
        )
        return None
    return result


class StringFormatterChecker:
    """String interpolation/formatter type checker.

    This class works closely together with checker.ExpressionChecker.
    """

    # Some services are provided by a TypeChecker instance.
    chk: mypy.checker.TypeChecker
    # This is shared with TypeChecker, but stored also here for convenience.
    msg: MessageBuilder
    # Some services are provided by a ExpressionChecker instance.
    exprchk: mypy.checkexpr.ExpressionChecker

    def __init__(
        self,
        exprchk: mypy.checkexpr.ExpressionChecker,
        chk: mypy.checker.TypeChecker,
        msg: MessageBuilder,
    ) -> None:
        """Construct an expression type checker."""
        self.chk = chk
        self.exprchk = exprchk
        self.msg = msg

    def check_str_format_call(self, call: CallExpr, format_value: str) -> None:
        """Perform more precise checks for str.format() calls when possible.

        Currently the checks are performed for:
          * Actual string literals
          * Literal types with string values
          * Final names with string values

        The checks that we currently perform:
          * Check generic validity (e.g. unmatched { or }, and {} in invalid positions)
          * Check consistency of specifiers' auto-numbering
          * Verify that replacements can be found for all conversion specifiers,
            and all arguments were used
          * Non-standard format specs are only allowed for types with custom __format__
          * Type check replacements with accessors applied (if any).
          * Verify that specifier type is known and matches replacement type
          * Perform special checks for some specifier types:
            - 'c' requires a single character string
            - 's' must not accept bytes
            - non-empty flags are only allowed for numeric types
        """
        conv_specs = parse_format_value(format_value, call, self.msg)
        if conv_specs is None:
            return
        if not self.auto_generate_keys(conv_specs, call):
            return
        self.check_specs_in_format_call(call, conv_specs, format_value)

    def check_specs_in_format_call(
        self, call: CallExpr, specs: list[ConversionSpecifier], format_value: str
    ) -> None:
        """Perform pairwise checks for conversion specifiers vs their replacements.

        The core logic for format checking is implemented in this method.
        """
        assert all(s.key for s in specs), "Keys must be auto-generated first!"
        replacements = self.find_replacements_in_call(call, [cast(str, s.key) for s in specs])
        assert len(replacements) == len(specs)
        for spec, repl in zip(specs, replacements):
            repl = self.apply_field_accessors(spec, repl, ctx=call)
            actual_type = repl.type if isinstance(repl, TempNode) else self.chk.lookup_type(repl)
            assert actual_type is not None

            # Special case custom formatting.
            if (
                spec.format_spec
                and spec.non_standard_format_spec
                and
                # Exclude "dynamic" specifiers (i.e. containing nested formatting).
                not ("{" in spec.format_spec or "}" in spec.format_spec)
            ):
                if (
                    not custom_special_method(actual_type, "__format__", check_all=True)
                    or spec.conversion
                ):
                    # TODO: add support for some custom specs like datetime?
                    self.msg.fail(
                        "Unrecognized format" ' specification "{}"'.format(spec.format_spec[1:]),
                        call,
                        code=codes.STRING_FORMATTING,
                    )
                    continue
            # Adjust expected and actual types.
            if not spec.conv_type:
                expected_type: Type | None = AnyType(TypeOfAny.special_form)
            else:
                assert isinstance(call.callee, MemberExpr)
                if isinstance(call.callee.expr, StrExpr):
                    format_str = call.callee.expr
                else:
                    format_str = StrExpr(format_value)
                expected_type = self.conversion_type(
                    spec.conv_type, call, format_str, format_call=True
                )
            if spec.conversion is not None:
                # If the explicit conversion is given, then explicit conversion is called _first_.
                if spec.conversion[1] not in "rsa":
                    self.msg.fail(
                        'Invalid conversion type "{}",'
                        ' must be one of "r", "s" or "a"'.format(spec.conversion[1]),
                        call,
                        code=codes.STRING_FORMATTING,
                    )
                actual_type = self.named_type("builtins.str")

            # Perform the checks for given types.
            if expected_type is None:
                continue

            a_type = get_proper_type(actual_type)
            actual_items = (
                get_proper_types(a_type.items) if isinstance(a_type, UnionType) else [a_type]
            )
            for a_type in actual_items:
                if custom_special_method(a_type, "__format__"):
                    continue
                self.check_placeholder_type(a_type, expected_type, call)
                self.perform_special_format_checks(spec, call, repl, a_type, expected_type)

    def perform_special_format_checks(
        self,
        spec: ConversionSpecifier,
        call: CallExpr,
        repl: Expression,
        actual_type: Type,
        expected_type: Type,
    ) -> None:
        # TODO: try refactoring to combine this logic with % formatting.
        if spec.conv_type == "c":
            if isinstance(repl, (StrExpr, BytesExpr)) and len(repl.value) != 1:
                self.msg.requires_int_or_char(call, format_call=True)
            c_typ = get_proper_type(self.chk.lookup_type(repl))
            if isinstance(c_typ, Instance) and c_typ.last_known_value:
                c_typ = c_typ.last_known_value
            if isinstance(c_typ, LiteralType) and isinstance(c_typ.value, str):
                if len(c_typ.value) != 1:
                    self.msg.requires_int_or_char(call, format_call=True)
        if (not spec.conv_type or spec.conv_type == "s") and not spec.conversion:
            if has_type_component(actual_type, "builtins.bytes") and not custom_special_method(
                actual_type, "__str__"
            ):
                self.msg.fail(
                    'If x = b\'abc\' then f"{x}" or "{}".format(x) produces "b\'abc\'", '
                    'not "abc". If this is desired behavior, use f"{x!r}" or "{!r}".format(x). '
                    "Otherwise, decode the bytes",
                    call,
                    code=codes.STR_BYTES_PY3,
                )
        if spec.flags:
            numeric_types = UnionType(
                [self.named_type("builtins.int"), self.named_type("builtins.float")]
            )
            if (
                spec.conv_type
                and spec.conv_type not in NUMERIC_TYPES_NEW
                or not spec.conv_type
                and not is_subtype(actual_type, numeric_types)
                and not custom_special_method(actual_type, "__format__")
            ):
                self.msg.fail(
                    "Numeric flags are only allowed for numeric types",
                    call,
                    code=codes.STRING_FORMATTING,
                )

    def find_replacements_in_call(self, call: CallExpr, keys: list[str]) -> list[Expression]:
        """Find replacement expression for every specifier in str.format() call.

        In case of an error use TempNode(AnyType).
        """
        result: list[Expression] = []
        used: set[Expression] = set()
        for key in keys:
            if key.isdecimal():
                expr = self.get_expr_by_position(int(key), call)
                if not expr:
                    self.msg.fail(
                        "Cannot find replacement for positional"
                        " format specifier {}".format(key),
                        call,
                        code=codes.STRING_FORMATTING,
                    )
                    expr = TempNode(AnyType(TypeOfAny.from_error))
            else:
                expr = self.get_expr_by_name(key, call)
                if not expr:
                    self.msg.fail(
                        "Cannot find replacement for named" ' format specifier "{}"'.format(key),
                        call,
                        code=codes.STRING_FORMATTING,
                    )
                    expr = TempNode(AnyType(TypeOfAny.from_error))
            result.append(expr)
            if not isinstance(expr, TempNode):
                used.add(expr)
        # Strictly speaking not using all replacements is not a type error, but most likely
        # a typo in user code, so we show an error like we do for % formatting.
        total_explicit = len([kind for kind in call.arg_kinds if kind in (ARG_POS, ARG_NAMED)])
        if len(used) < total_explicit:
            self.msg.too_many_string_formatting_arguments(call)
        return result

    def get_expr_by_position(self, pos: int, call: CallExpr) -> Expression | None:
        """Get positional replacement expression from '{0}, {1}'.format(x, y, ...) call.

        If the type is from *args, return TempNode(<item type>). Return None in case of
        an error.
        """
        pos_args = [arg for arg, kind in zip(call.args, call.arg_kinds) if kind == ARG_POS]
        if pos < len(pos_args):
            return pos_args[pos]
        star_args = [arg for arg, kind in zip(call.args, call.arg_kinds) if kind == ARG_STAR]
        if not star_args:
            return None

        # Fall back to *args when present in call.
        star_arg = star_args[0]
        varargs_type = get_proper_type(self.chk.lookup_type(star_arg))
        if not isinstance(varargs_type, Instance) or not varargs_type.type.has_base(
            "typing.Sequence"
        ):
            # Error should be already reported.
            return TempNode(AnyType(TypeOfAny.special_form))
        iter_info = self.chk.named_generic_type(
            "typing.Sequence", [AnyType(TypeOfAny.special_form)]
        ).type
        return TempNode(map_instance_to_supertype(varargs_type, iter_info).args[0])

    def get_expr_by_name(self, key: str, call: CallExpr) -> Expression | None:
        """Get named replacement expression from '{name}'.format(name=...) call.

        If the type is from **kwargs, return TempNode(<item type>). Return None in case of
        an error.
        """
        named_args = [
            arg
            for arg, kind, name in zip(call.args, call.arg_kinds, call.arg_names)
            if kind == ARG_NAMED and name == key
        ]
        if named_args:
            return named_args[0]
        star_args_2 = [arg for arg, kind in zip(call.args, call.arg_kinds) if kind == ARG_STAR2]
        if not star_args_2:
            return None
        star_arg_2 = star_args_2[0]
        kwargs_type = get_proper_type(self.chk.lookup_type(star_arg_2))
        if not isinstance(kwargs_type, Instance) or not kwargs_type.type.has_base(
            "typing.Mapping"
        ):
            # Error should be already reported.
            return TempNode(AnyType(TypeOfAny.special_form))
        any_type = AnyType(TypeOfAny.special_form)
        mapping_info = self.chk.named_generic_type("typing.Mapping", [any_type, any_type]).type
        return TempNode(map_instance_to_supertype(kwargs_type, mapping_info).args[1])

    def auto_generate_keys(self, all_specs: list[ConversionSpecifier], ctx: Context) -> bool:
        """Translate '{} {name} {}' to '{0} {name} {1}'.

        Return True if generation was successful, otherwise report an error and return false.
        """
        some_defined = any(s.key and s.key.isdecimal() for s in all_specs)
        all_defined = all(bool(s.key) for s in all_specs)
        if some_defined and not all_defined:
            self.msg.fail(
                "Cannot combine automatic field numbering and manual field specification",
                ctx,
                code=codes.STRING_FORMATTING,
            )
            return False
        if all_defined:
            return True
        next_index = 0
        for spec in all_specs:
            if not spec.key:
                str_index = str(next_index)
                spec.key = str_index
                # Update also the full field (i.e. turn {.x} into {0.x}).
                if not spec.field:
                    spec.field = str_index
                else:
                    spec.field = str_index + spec.field
                next_index += 1
        return True

    def apply_field_accessors(
        self, spec: ConversionSpecifier, repl: Expression, ctx: Context
    ) -> Expression:
        """Transform and validate expr in '{.attr[item]}'.format(expr) into expr.attr['item'].

        If validation fails, return TempNode(AnyType).
        """
        assert spec.key, "Keys must be auto-generated first!"
        if spec.field == spec.key:
            return repl
        assert spec.field

        temp_errors = Errors(self.chk.options)
        dummy = DUMMY_FIELD_NAME + spec.field[len(spec.key) :]
        temp_ast: Node = parse(
            dummy, fnam="<format>", module=None, options=self.chk.options, errors=temp_errors
        )
        if temp_errors.is_errors():
            self.msg.fail(
                f'Syntax error in format specifier "{spec.field}"',
                ctx,
                code=codes.STRING_FORMATTING,
            )
            return TempNode(AnyType(TypeOfAny.from_error))

        # These asserts are guaranteed by the original regexp.
        assert isinstance(temp_ast, MypyFile)
        temp_ast = temp_ast.defs[0]
        assert isinstance(temp_ast, ExpressionStmt)
        temp_ast = temp_ast.expr
        if not self.validate_and_transform_accessors(temp_ast, repl, spec, ctx=ctx):
            return TempNode(AnyType(TypeOfAny.from_error))

        # Check if there are any other errors (like missing members).
        # TODO: fix column to point to actual start of the format specifier _within_ string.
        temp_ast.line = ctx.line
        temp_ast.column = ctx.column
        self.exprchk.accept(temp_ast)
        return temp_ast

    def validate_and_transform_accessors(
        self,
        temp_ast: Expression,
        original_repl: Expression,
        spec: ConversionSpecifier,
        ctx: Context,
    ) -> bool:
        """Validate and transform (in-place) format field accessors.

        On error, report it and return False. The transformations include replacing the dummy
        variable with actual replacement expression and translating any name expressions in an
        index into strings, so that this will work:

            class User(TypedDict):
                name: str
                id: int
            u: User
            '{[id]:d} -> {[name]}'.format(u)
        """
        if not isinstance(temp_ast, (MemberExpr, IndexExpr)):
            self.msg.fail(
                "Only index and member expressions are allowed in"
                ' format field accessors; got "{}"'.format(spec.field),
                ctx,
                code=codes.STRING_FORMATTING,
            )
            return False
        if isinstance(temp_ast, MemberExpr):
            node = temp_ast.expr
        else:
            node = temp_ast.base
            if not isinstance(temp_ast.index, (NameExpr, IntExpr)):
                assert spec.key, "Call this method only after auto-generating keys!"
                assert spec.field
                self.msg.fail(
                    "Invalid index expression in format field"
                    ' accessor "{}"'.format(spec.field[len(spec.key) :]),
                    ctx,
                    code=codes.STRING_FORMATTING,
                )
                return False
            if isinstance(temp_ast.index, NameExpr):
                temp_ast.index = StrExpr(temp_ast.index.name)
        if isinstance(node, NameExpr) and node.name == DUMMY_FIELD_NAME:
            # Replace it with the actual replacement expression.
            assert isinstance(temp_ast, (IndexExpr, MemberExpr))  # XXX: this is redundant
            if isinstance(temp_ast, IndexExpr):
                temp_ast.base = original_repl
            else:
                temp_ast.expr = original_repl
            return True
        node.line = ctx.line
        node.column = ctx.column
        return self.validate_and_transform_accessors(
            node, original_repl=original_repl, spec=spec, ctx=ctx
        )

    # TODO: In Python 3, the bytes formatting has a more restricted set of options
    #       compared to string formatting.
    def check_str_interpolation(self, expr: FormatStringExpr, replacements: Expression) -> Type:
        """Check the types of the 'replacements' in a string interpolation
        expression: str % replacements.
        """
        self.exprchk.accept(expr)
        specifiers = parse_conversion_specifiers(expr.value)
        has_mapping_keys = self.analyze_conversion_specifiers(specifiers, expr)
        if isinstance(expr, BytesExpr) and self.chk.options.python_version < (3, 5):
            self.msg.fail(
                "Bytes formatting is only supported in Python 3.5 and later",
                replacements,
                code=codes.STRING_FORMATTING,
            )
            return AnyType(TypeOfAny.from_error)

        if has_mapping_keys is None:
            pass  # Error was reported
        elif has_mapping_keys:
            self.check_mapping_str_interpolation(specifiers, replacements, expr)
        else:
            self.check_simple_str_interpolation(specifiers, replacements, expr)

        if isinstance(expr, BytesExpr):
            return self.named_type("builtins.bytes")
        elif isinstance(expr, StrExpr):
            return self.named_type("builtins.str")
        else:
            assert False

    def analyze_conversion_specifiers(
        self, specifiers: list[ConversionSpecifier], context: Context
    ) -> bool | None:
        has_star = any(specifier.has_star() for specifier in specifiers)
        has_key = any(specifier.has_key() for specifier in specifiers)
        all_have_keys = all(
            specifier.has_key() or specifier.conv_type == "%" for specifier in specifiers
        )

        if has_key and has_star:
            self.msg.string_interpolation_with_star_and_key(context)
            return None
        if has_key and not all_have_keys:
            self.msg.string_interpolation_mixing_key_and_non_keys(context)
            return None
        return has_key

    def check_simple_str_interpolation(
        self,
        specifiers: list[ConversionSpecifier],
        replacements: Expression,
        expr: FormatStringExpr,
    ) -> None:
        """Check % string interpolation with positional specifiers '%s, %d' % ('yes, 42')."""
        checkers = self.build_replacement_checkers(specifiers, replacements, expr)
        if checkers is None:
            return

        rhs_type = get_proper_type(self.accept(replacements))
        rep_types: list[Type] = []
        if isinstance(rhs_type, TupleType):
            rep_types = rhs_type.items
        elif isinstance(rhs_type, AnyType):
            return
        elif isinstance(rhs_type, Instance) and rhs_type.type.fullname == "builtins.tuple":
            # Assume that an arbitrary-length tuple has the right number of items.
            rep_types = [rhs_type.args[0]] * len(checkers)
        elif isinstance(rhs_type, UnionType):
            for typ in rhs_type.relevant_items():
                temp_node = TempNode(typ)
                temp_node.line = replacements.line
                self.check_simple_str_interpolation(specifiers, temp_node, expr)
            return
        else:
            rep_types = [rhs_type]

        if len(checkers) > len(rep_types):
            # Only check the fix-length Tuple type. Other Iterable types would skip.
            if is_subtype(rhs_type, self.chk.named_type("typing.Iterable")) and not isinstance(
                rhs_type, TupleType
            ):
                return
            else:
                self.msg.too_few_string_formatting_arguments(replacements)
        elif len(checkers) < len(rep_types):
            self.msg.too_many_string_formatting_arguments(replacements)
        else:
            if len(checkers) == 1:
                check_node, check_type = checkers[0]
                if isinstance(rhs_type, TupleType) and len(rhs_type.items) == 1:
                    check_type(rhs_type.items[0])
                else:
                    check_node(replacements)
            elif isinstance(replacements, TupleExpr) and not any(
                isinstance(item, StarExpr) for item in replacements.items
            ):
                for checks, rep_node in zip(checkers, replacements.items):
                    check_node, check_type = checks
                    check_node(rep_node)
            else:
                for checks, rep_type in zip(checkers, rep_types):
                    check_node, check_type = checks
                    check_type(rep_type)

    def check_mapping_str_interpolation(
        self,
        specifiers: list[ConversionSpecifier],
        replacements: Expression,
        expr: FormatStringExpr,
    ) -> None:
        """Check % string interpolation with names specifiers '%(name)s' % {'name': 'John'}."""
        if isinstance(replacements, DictExpr) and all(
            isinstance(k, (StrExpr, BytesExpr)) for k, v in replacements.items
        ):
            mapping: dict[str, Type] = {}
            for k, v in replacements.items:
                if isinstance(expr, BytesExpr):
                    # Special case: for bytes formatting keys must be bytes.
                    if not isinstance(k, BytesExpr):
                        self.msg.fail(
                            "Dictionary keys in bytes formatting must be bytes, not strings",
                            expr,
                            code=codes.STRING_FORMATTING,
                        )
                key_str = cast(FormatStringExpr, k).value
                mapping[key_str] = self.accept(v)

            for specifier in specifiers:
                if specifier.conv_type == "%":
                    # %% is allowed in mappings, no checking is required
                    continue
                assert specifier.key is not None
                if specifier.key not in mapping:
                    self.msg.key_not_in_mapping(specifier.key, replacements)
                    return
                rep_type = mapping[specifier.key]
                assert specifier.conv_type is not None
                expected_type = self.conversion_type(specifier.conv_type, replacements, expr)
                if expected_type is None:
                    return
                self.chk.check_subtype(
                    rep_type,
                    expected_type,
                    replacements,
                    message_registry.INCOMPATIBLE_TYPES_IN_STR_INTERPOLATION,
                    "expression has type",
                    f"placeholder with key '{specifier.key}' has type",
                    code=codes.STRING_FORMATTING,
                )
                if specifier.conv_type == "s":
                    self.check_s_special_cases(expr, rep_type, expr)
        else:
            rep_type = self.accept(replacements)
            dict_type = self.build_dict_type(expr)
            self.chk.check_subtype(
                rep_type,
                dict_type,
                replacements,
                message_registry.FORMAT_REQUIRES_MAPPING,
                "expression has type",
                "expected type for mapping is",
                code=codes.STRING_FORMATTING,
            )

    def build_dict_type(self, expr: FormatStringExpr) -> Type:
        """Build expected mapping type for right operand in % formatting."""
        any_type = AnyType(TypeOfAny.special_form)
        if isinstance(expr, BytesExpr):
            bytes_type = self.chk.named_generic_type("builtins.bytes", [])
            return self.chk.named_generic_type(
                "_typeshed.SupportsKeysAndGetItem", [bytes_type, any_type]
            )
        elif isinstance(expr, StrExpr):
            str_type = self.chk.named_generic_type("builtins.str", [])
            return self.chk.named_generic_type(
                "_typeshed.SupportsKeysAndGetItem", [str_type, any_type]
            )
        else:
            assert False, "Unreachable"

    def build_replacement_checkers(
        self, specifiers: list[ConversionSpecifier], context: Context, expr: FormatStringExpr
    ) -> list[Checkers] | None:
        checkers: list[Checkers] = []
        for specifier in specifiers:
            checker = self.replacement_checkers(specifier, context, expr)
            if checker is None:
                return None
            checkers.extend(checker)
        return checkers

    def replacement_checkers(
        self, specifier: ConversionSpecifier, context: Context, expr: FormatStringExpr
    ) -> list[Checkers] | None:
        """Returns a list of tuples of two functions that check whether a replacement is
        of the right type for the specifier. The first function takes a node and checks
        its type in the right type context. The second function just checks a type.
        """
        checkers: list[Checkers] = []

        if specifier.width == "*":
            checkers.append(self.checkers_for_star(context))
        if specifier.precision == "*":
            checkers.append(self.checkers_for_star(context))

        if specifier.conv_type == "c":
            c = self.checkers_for_c_type(specifier.conv_type, context, expr)
            if c is None:
                return None
            checkers.append(c)
        elif specifier.conv_type is not None and specifier.conv_type != "%":
            c = self.checkers_for_regular_type(specifier.conv_type, context, expr)
            if c is None:
                return None
            checkers.append(c)
        return checkers

    def checkers_for_star(self, context: Context) -> Checkers:
        """Returns a tuple of check functions that check whether, respectively,
        a node or a type is compatible with a star in a conversion specifier.
        """
        expected = self.named_type("builtins.int")

        def check_type(type: Type) -> bool:
            expected = self.named_type("builtins.int")
            return self.chk.check_subtype(
                type, expected, context, "* wants int", code=codes.STRING_FORMATTING
            )

        def check_expr(expr: Expression) -> None:
            type = self.accept(expr, expected)
            check_type(type)

        return check_expr, check_type

    def check_placeholder_type(self, typ: Type, expected_type: Type, context: Context) -> bool:
        return self.chk.check_subtype(
            typ,
            expected_type,
            context,
            message_registry.INCOMPATIBLE_TYPES_IN_STR_INTERPOLATION,
            "expression has type",
            "placeholder has type",
            code=codes.STRING_FORMATTING,
        )

    def checkers_for_regular_type(
        self, conv_type: str, context: Context, expr: FormatStringExpr
    ) -> Checkers | None:
        """Returns a tuple of check functions that check whether, respectively,
        a node or a type is compatible with 'type'. Return None in case of an error.
        """
        expected_type = self.conversion_type(conv_type, context, expr)
        if expected_type is None:
            return None

        def check_type(typ: Type) -> bool:
            assert expected_type is not None
            ret = self.check_placeholder_type(typ, expected_type, context)
            if ret and conv_type == "s":
                ret = self.check_s_special_cases(expr, typ, context)
            return ret

        def check_expr(expr: Expression) -> None:
            type = self.accept(expr, expected_type)
            check_type(type)

        return check_expr, check_type

    def check_s_special_cases(self, expr: FormatStringExpr, typ: Type, context: Context) -> bool:
        """Additional special cases for %s in bytes vs string context."""
        if isinstance(expr, StrExpr):
            # Couple special cases for string formatting.
            if has_type_component(typ, "builtins.bytes"):
                self.msg.fail(
                    'If x = b\'abc\' then "%s" % x produces "b\'abc\'", not "abc". '
                    'If this is desired behavior use "%r" % x. Otherwise, decode the bytes',
                    context,
                    code=codes.STR_BYTES_PY3,
                )
                return False
        if isinstance(expr, BytesExpr):
            # A special case for bytes formatting: b'%s' actually requires bytes on Python 3.
            if has_type_component(typ, "builtins.str"):
                self.msg.fail(
                    "On Python 3 b'%s' requires bytes, not string",
                    context,
                    code=codes.STRING_FORMATTING,
                )
                return False
        return True

    def checkers_for_c_type(
        self, type: str, context: Context, format_expr: FormatStringExpr
    ) -> Checkers | None:
        """Returns a tuple of check functions that check whether, respectively,
        a node or a type is compatible with 'type' that is a character type.
        """
        expected_type = self.conversion_type(type, context, format_expr)
        if expected_type is None:
            return None

        def check_type(type: Type) -> bool:
            assert expected_type is not None
            if isinstance(format_expr, BytesExpr):
                err_msg = '"%c" requires an integer in range(256) or a single byte'
            else:
                err_msg = '"%c" requires int or char'
            return self.chk.check_subtype(
                type,
                expected_type,
                context,
                err_msg,
                "expression has type",
                code=codes.STRING_FORMATTING,
            )

        def check_expr(expr: Expression) -> None:
            """int, or str with length 1"""
            type = self.accept(expr, expected_type)
            # We need further check with expr to make sure that
            # it has exact one char or one single byte.
            if check_type(type):
                # Python 3 doesn't support b'%c' % str
                if (
                    isinstance(format_expr, BytesExpr)
                    and isinstance(expr, BytesExpr)
                    and len(expr.value) != 1
                ):
                    self.msg.requires_int_or_single_byte(context)
                elif isinstance(expr, (StrExpr, BytesExpr)) and len(expr.value) != 1:
                    self.msg.requires_int_or_char(context)

        return check_expr, check_type

    def conversion_type(
        self, p: str, context: Context, expr: FormatStringExpr, format_call: bool = False
    ) -> Type | None:
        """Return the type that is accepted for a string interpolation conversion specifier type.

        Note that both Python's float (e.g. %f) and integer (e.g. %d)
        specifier types accept both float and integers.

        The 'format_call' argument indicates whether this type came from % interpolation or from
        a str.format() call, the meaning of few formatting types are different.
        """
        NUMERIC_TYPES = NUMERIC_TYPES_NEW if format_call else NUMERIC_TYPES_OLD
        INT_TYPES = REQUIRE_INT_NEW if format_call else REQUIRE_INT_OLD
        if p == "b" and not format_call:
            if self.chk.options.python_version < (3, 5):
                self.msg.fail(
                    'Format character "b" is only supported in Python 3.5 and later',
                    context,
                    code=codes.STRING_FORMATTING,
                )
                return None
            if not isinstance(expr, BytesExpr):
                self.msg.fail(
                    'Format character "b" is only supported on bytes patterns',
                    context,
                    code=codes.STRING_FORMATTING,
                )
                return None
            return self.named_type("builtins.bytes")
        elif p == "a":
            # TODO: return type object?
            return AnyType(TypeOfAny.special_form)
        elif p in ["s", "r"]:
            return AnyType(TypeOfAny.special_form)
        elif p in NUMERIC_TYPES:
            if p in INT_TYPES:
                numeric_types = [self.named_type("builtins.int")]
            else:
                numeric_types = [
                    self.named_type("builtins.int"),
                    self.named_type("builtins.float"),
                ]
                if not format_call:
                    if p in FLOAT_TYPES:
                        numeric_types.append(self.named_type("typing.SupportsFloat"))
                    else:
                        numeric_types.append(self.named_type("typing.SupportsInt"))
            return UnionType.make_union(numeric_types)
        elif p in ["c"]:
            if isinstance(expr, BytesExpr):
                return UnionType(
                    [self.named_type("builtins.int"), self.named_type("builtins.bytes")]
                )
            else:
                return UnionType(
                    [self.named_type("builtins.int"), self.named_type("builtins.str")]
                )
        else:
            self.msg.unsupported_placeholder(p, context)
            return None

    #
    # Helpers
    #

    def named_type(self, name: str) -> Instance:
        """Return an instance type with type given by the name and no type
        arguments. Alias for TypeChecker.named_type.
        """
        return self.chk.named_type(name)

    def accept(self, expr: Expression, context: Type | None = None) -> Type:
        """Type check a node. Alias for TypeChecker.accept."""
        return self.chk.expr_checker.accept(expr, context)


def has_type_component(typ: Type, fullname: str) -> bool:
    """Is this a specific instance type, or a union that contains it?

    We use this ad-hoc function instead of a proper visitor or subtype check
    because some str vs bytes errors are strictly speaking not runtime errors,
    but rather highly counter-intuitive behavior. This is similar to what is used for
    --strict-equality.
    """
    typ = get_proper_type(typ)
    if isinstance(typ, Instance):
        return typ.type.has_base(fullname)
    elif isinstance(typ, TypeVarType):
        return has_type_component(typ.upper_bound, fullname) or any(
            has_type_component(v, fullname) for v in typ.values
        )
    elif isinstance(typ, UnionType):
        return any(has_type_component(t, fullname) for t in typ.relevant_items())
    return False
