Skip to content

Generate better error message for incompatible **kwargs #8874

Description

@JukkaL

This output is from #8772:

$ mypy test.py 
test.py:6: error: Argument 2 to "dumps" has incompatible type "**Dict[str, int]"; expected "bool"
test.py:6: error: Argument 2 to "dumps" has incompatible type "**Dict[str, int]"; expected "Optional[Type[JSONEncoder]]"
test.py:6: error: Argument 2 to "dumps" has incompatible type "**Dict[str, int]"; expected "Optional[Tuple[str, str]]"
test.py:6: error: Argument 2 to "dumps" has incompatible type "**Dict[str, int]"; expected "Optional[Callable[[Any], Any]]"
Found 4 errors in 1 file (checked 1 source file)

The error messages are pretty confusing. We should special case this and produce a customized error message that explains the situation better.

Here's the code that triggers the errors:

import json

json_kwargs = dict(indent=2)

json.dumps({}, **json_kwargs)

Some ideas about what to do:

  • Generate a single error message instead of multiple ones.
  • Add a note suggesting the use of Dict[str, Any] or a TypedDict type for the **kwargs argument.
  • Maybe also explain that mypy matches the value type against all arguments, or add a link to documentation (add something to common issues, for example).

Activity

  1. rohitkg98 commented on May 31, 2020

    @rohitkg98

    I would like to work on this. Seems straight forward, just need to change code here, right?

  2. rohitkg98 commented on Jun 7, 2020

    @rohitkg98

    I believe there should be multiple error messages, to inform of all callable argument type mismatch.

  3. Uttam-Singhh commented on Feb 12, 2021

    @Uttam-Singhh

    Can I work on it??

  4. rohitkg98 commented on Feb 12, 2021

    @rohitkg98

    Sure, I have not been able to continue work on it, feel free to do so. Take a look at the PR I made, let me know if you need help!

  5. Uttam-Singhh commented on Feb 12, 2021

    @Uttam-Singhh

    @rohitkg98 I was looking at your PR and I saw that it passed all the checks then why it was not merged?
    I am new to open source. Can you please help and guide me on how to work on this issue & why was your code not merged?

  6. noob8boi commented on Nov 5, 2021

    @noob8boi
    Contributor

    is this issue still open?

  7. JukkaL commented on Jul 16, 2022

    @JukkaL
    CollaboratorAuthor

    One idea for a note:

    ...: note: Consider using a TypedDict type or "Dict[str, Any]" for the ** argument
    
  8. Arzugar commented on Apr 7, 2024

    @Arzugar

    Hi, I plan to work on this issue.
    My take on this issue is that as discussed in #8772 this behavior is to be expected, and an error message should indeed be thrown.
    But the message needs improvement. I will implement what has been proposed in PR #8960 by gvanrossum and modify existing tests accordingly in order to get it merged.

    As a new and inexperienced contributor I'm open to any suggestions or comments.

  9. Arzugar commented on Apr 10, 2024

    @Arzugar

    Hello,
    I could really use someone's opinion on this case :

    def f(a: int = 42, b: str = "hello world"): ...
    
    
    d = dict(a=3, b="Bye")  # is inferred as Dict[str, object]
    f(**d)

    This code cannot be statically typed, and so we should indicate to the user a way of making it work.
    My question is : which of the following solution is the best ? My personal opinion is that the first one should be preferred, because it seems safer.

    Solution 1

    from typing import TypedDict
    
    class Params(TypedDict):
        a: int
        b: str
    
    
    d: Params = dict(a=3, b="hello")
    
    f(**d)

    Solution 2

    d: Dict[str, Any] = dict(a=3, b="hello")
    f(**d)
  10. hauntsaninja commented on Apr 10, 2024

    @hauntsaninja
    Collaborator

    I think both have their place, the note Jukka suggests here #8874 (comment) seems like a good phrasing

  11. yourlocaljosh commented on Mar 31, 2026

    @yourlocaljosh

    Hi, I've been looking into this issue and would like to work on a fix. I've reviewed the prior attempt in #17186 and noticed it stalled after a review comment suggesting the note should reference **kwargs: Any annotation syntax rather than Dict[str, Any], since that's what a user would actually write in their function signature. I plan to address that feedback in a fresh implementation. I'll comment here before opening a PR if I have questions about the intended approach.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions