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

Method check_mapping_str_interpolation

mypy/checkstrformat.py:787–845  ·  view source on GitHub ↗

Check % string interpolation with names specifiers '%(name)s' % {'name': 'John'}.

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

Source from the content-addressed store, hash-verified

785 check_type(rep_type)
786
787 def check_mapping_str_interpolation(
788 self,
789 specifiers: list[ConversionSpecifier],
790 replacements: Expression,
791 expr: FormatStringExpr,
792 ) -> None:
793 """Check % string interpolation with names specifiers '%(name)s' % {'name': 'John'}."""
794 if isinstance(replacements, DictExpr) and all(
795 isinstance(k, (StrExpr, BytesExpr)) for k, v in replacements.items
796 ):
797 mapping: dict[str, Type] = {}
798 for k, v in replacements.items:
799 if isinstance(expr, BytesExpr):
800 # Special case: for bytes formatting keys must be bytes.
801 if not isinstance(k, BytesExpr):
802 self.msg.fail(
803 "Dictionary keys in bytes formatting must be bytes, not strings",
804 expr,
805 code=codes.STRING_FORMATTING,
806 )
807 key_str = cast(FormatStringExpr, k).value
808 mapping[key_str] = self.accept(v)
809
810 for specifier in specifiers:
811 if specifier.conv_type == "%":
812 # %% is allowed in mappings, no checking is required
813 continue
814 assert specifier.key is not None
815 if specifier.key not in mapping:
816 self.msg.key_not_in_mapping(specifier.key, replacements)
817 return
818 rep_type = mapping[specifier.key]
819 assert specifier.conv_type is not None
820 expected_type = self.conversion_type(specifier.conv_type, replacements, expr)
821 if expected_type is None:
822 return
823 self.chk.check_subtype(
824 rep_type,
825 expected_type,
826 replacements,
827 message_registry.INCOMPATIBLE_TYPES_IN_STR_INTERPOLATION,
828 "expression has type",
829 f"placeholder with key '{specifier.key}' has type",
830 code=codes.STRING_FORMATTING,
831 )
832 if specifier.conv_type == "s":
833 self.check_s_special_cases(expr, rep_type, expr)
834 else:
835 rep_type = self.accept(replacements)
836 dict_type = self.build_dict_type(expr)
837 self.chk.check_subtype(
838 rep_type,
839 dict_type,
840 replacements,
841 message_registry.FORMAT_REQUIRES_MAPPING,
842 "expression has type",
843 "expected type for mapping is",
844 code=codes.STRING_FORMATTING,

Callers 1

Calls 9

acceptMethod · 0.95
conversion_typeMethod · 0.95
check_s_special_casesMethod · 0.95
build_dict_typeMethod · 0.95
isinstanceFunction · 0.85
allFunction · 0.85
key_not_in_mappingMethod · 0.80
failMethod · 0.45
check_subtypeMethod · 0.45

Tested by

no test coverage detected