Skip to content

Generate better error message for incompatible **kwargs #8874

Open
@JukkaL

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

rohitkg98

rohitkg98 commented on May 31, 2020

@rohitkg98

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

rohitkg98

rohitkg98 commented on Jun 7, 2020

@rohitkg98

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

Uttam-Singhh

Uttam-Singhh commented on Feb 12, 2021

@Uttam-Singhh

Can I work on it??

rohitkg98

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!

Uttam-Singhh

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?

noob8boi

noob8boi commented on Nov 5, 2021

@noob8boi
Contributor

is this issue still open?

JukkaL

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
linked a pull request that will close this issue on Jul 16, 2022
Arzugar

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.

Arzugar

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)
hauntsaninja

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Generate better error message for incompatible **kwargs · Issue #8874 · python/mypy