MCPcopy Index your code
hub / github.com/python/mypy / check_simple_str_interpolation

Method check_simple_str_interpolation

mypy/checkstrformat.py:714–785  ·  view source on GitHub ↗

Check % string interpolation with positional specifiers '%s, %d' % ('yes, 42').

(
        self,
        specifiers: list[ConversionSpecifier],
        replacements: Expression,
        expr: FormatStringExpr,
    )

Source from the content-addressed store, hash-verified

712 return has_key
713
714 def check_simple_str_interpolation(
715 self,
716 specifiers: list[ConversionSpecifier],
717 replacements: Expression,
718 expr: FormatStringExpr,
719 ) -> None:
720 """Check % string interpolation with positional specifiers '%s, %d' % ('yes, 42')."""
721 checkers = self.build_replacement_checkers(specifiers, replacements, expr)
722 if checkers is None:
723 return
724
725 rhs_type = get_proper_type(self.accept(replacements))
726 rep_types: list[Type] = []
727 if isinstance(rhs_type, TupleType):
728 rep_types = rhs_type.items
729 unpack_index = find_unpack_in_list(rep_types)
730 if unpack_index is not None:
731 # TODO: we should probably warn about potentially short tuple.
732 # However, without special-casing for tuple(f(i) for in other_tuple)
733 # this causes false positive on mypy self-check in report.py.
734 extras = max(0, len(checkers) - len(rep_types) + 1)
735 unpacked = rep_types[unpack_index]
736 assert isinstance(unpacked, UnpackType)
737 unpacked = get_proper_type(unpacked.type)
738 if isinstance(unpacked, TypeVarTupleType):
739 unpacked = get_proper_type(unpacked.upper_bound)
740 assert (
741 isinstance(unpacked, Instance) and unpacked.type.fullname == "builtins.tuple"
742 )
743 unpack_items = [unpacked.args[0]] * extras
744 rep_types = rep_types[:unpack_index] + unpack_items + rep_types[unpack_index + 1 :]
745 elif isinstance(rhs_type, AnyType):
746 return
747 elif isinstance(rhs_type, Instance) and rhs_type.type.fullname == "builtins.tuple":
748 # Assume that an arbitrary-length tuple has the right number of items.
749 rep_types = [rhs_type.args[0]] * len(checkers)
750 elif isinstance(rhs_type, UnionType):
751 for typ in rhs_type.relevant_items():
752 temp_node = TempNode(typ)
753 temp_node.line = replacements.line
754 self.check_simple_str_interpolation(specifiers, temp_node, expr)
755 return
756 else:
757 rep_types = [rhs_type]
758
759 if len(checkers) > len(rep_types):
760 # Only check the fix-length Tuple type. Other Iterable types would skip.
761 if is_subtype(rhs_type, self.chk.named_type("typing.Iterable")) and not isinstance(
762 rhs_type, TupleType
763 ):
764 return
765 else:
766 self.msg.too_few_string_formatting_arguments(replacements)
767 elif len(checkers) < len(rep_types):
768 self.msg.too_many_string_formatting_arguments(replacements)
769 else:
770 if len(checkers) == 1:
771 check_node, check_type = checkers[0]

Callers 1

Calls 15

acceptMethod · 0.95
get_proper_typeFunction · 0.90
find_unpack_in_listFunction · 0.90
TempNodeClass · 0.90
is_subtypeFunction · 0.90
isinstanceFunction · 0.85
maxFunction · 0.85
lenFunction · 0.85
anyFunction · 0.85
zipFunction · 0.85
relevant_itemsMethod · 0.80

Tested by

no test coverage detected