diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py index 8288b676b52e..d8a861b8d59e 100644 --- a/mypy/checkexpr.py +++ b/mypy/checkexpr.py @@ -5432,6 +5432,16 @@ def visit_dict_expr(self, e: DictExpr) -> Type: expected_types: list[Type] = [] for key, value in e.items: if key is None: + # This is a **expr unpacking. Check that the expression has string keys. + value_type = get_proper_type(self.accept(value)) + # NEW: Allow Any or Unbound types to reduce false positives in external libraries + if isinstance(value_type, (AnyType, UnboundType)): + pass + elif not self.is_valid_keyword_var_arg(value_type): + is_mapping = is_subtype( + value_type, self.chk.named_type("_typeshed.SupportsKeysAndGetItem") + ) + self.msg.invalid_keyword_var_arg(value_type, is_mapping, value) args.append(value) expected_types.append( self.chk.named_generic_type("_typeshed.SupportsKeysAndGetItem", [kt, vt])