Skip to content

Improve error message for incompatible **kwargs#21239

Open
yosofbadr wants to merge 1 commit intopython:masterfrom
yosofbadr:fix/kwargs-error-message
Open

Improve error message for incompatible **kwargs#21239
yosofbadr wants to merge 1 commit intopython:masterfrom
yosofbadr:fix/kwargs-error-message

Conversation

@yosofbadr
Copy link
Copy Markdown

Summary

Fixes #8874

When a function is called with **kwargs whose value type is incompatible with the expected parameter types, mypy produced confusing error messages with no actionable guidance. For example:

test.py:4: error: Argument 1 to "f" has incompatible type "**Dict[str, int]"; expected "str"

This PR adds a note to these errors suggesting the user annotate the ** argument as **kwargs: Any or use a TypedDict for more precise typing:

test.py:4: error: Argument 1 to "f" has incompatible type "**Dict[str, int]"; expected "str"
test.py:4: note: Consider annotating the ** argument as "**kwargs: Any" or using a TypedDict

The note is shown whenever arg_kind == ARG_STAR2 and the argument type is an Instance (e.g., dict, Mapping, or their subclasses). It is intentionally not shown for TypedDict or ParamSpec argument types, as those already provide precise per-key type checking or have different semantics.

Changes

  • mypy/messages.py: Added a note after the incompatible **kwargs error message suggesting **kwargs: Any or TypedDict.
  • Test files: Updated 8 existing test files to expect the new note, and added a new testIncompatibleKwargsNote test case.

Test plan

  • All targeted test cases pass (testKwargs*, testParamSpec*, testFunctools*, testTypedDictAsStarStarArgCalleeKwargs, etc.)
  • New testIncompatibleKwargsNote test case added and passes
  • TypedDict ** arguments do NOT receive the note (verified via testTypedDictAsStarStarArgCalleeKwargs)

When a function is called with **kwargs whose value type is incompatible
with the expected parameter types, mypy now adds a note suggesting the
user annotate the ** argument as "**kwargs: Any" or use a TypedDict type
for more precise typing.

This addresses the confusing error messages reported in python#8874 where
multiple errors like 'has incompatible type "**Dict[str, int]";
expected "bool"' gave no actionable guidance on how to fix the issue.

Fixes python#8874
@github-actions
Copy link
Copy Markdown
Contributor

Diff from mypy_primer, showing the effect of this PR on open source code:

pyinstrument (https://github.com/joerick/pyinstrument)
+ pyinstrument/context_manager.py:40: note: Consider annotating the ** argument as "**kwargs: Any" or using a TypedDict
+ pyinstrument/context_manager.py:63: note: Consider annotating the ** argument as "**kwargs: Any" or using a TypedDict

prefect (https://github.com/PrefectHQ/prefect)
+ src/prefect/deployments/runner.py:870: note: Consider annotating the ** argument as "**kwargs: Any" or using a TypedDict
+ src/prefect/tasks.py:2259: note: Consider annotating the ** argument as "**kwargs: Any" or using a TypedDict
+ src/prefect/cli/deploy/_schedules.py:70: note: Consider annotating the ** argument as "**kwargs: Any" or using a TypedDict

colour (https://github.com/colour-science/colour)
+ colour/plotting/volume.py:785: note: Consider annotating the ** argument as "**kwargs: Any" or using a TypedDict
+ colour/plotting/phenomena.py:1323: note: Consider annotating the ** argument as "**kwargs: Any" or using a TypedDict
+ colour/plotting/phenomena.py:1370: note: Consider annotating the ** argument as "**kwargs: Any" or using a TypedDict
+ colour/plotting/phenomena.py:1482: note: Consider annotating the ** argument as "**kwargs: Any" or using a TypedDict
+ colour/plotting/phenomena.py:1538: note: Consider annotating the ** argument as "**kwargs: Any" or using a TypedDict
+ colour/plotting/models.py:1984: note: Consider annotating the ** argument as "**kwargs: Any" or using a TypedDict
+ colour/plotting/models.py:1988: note: Consider annotating the ** argument as "**kwargs: Any" or using a TypedDict
+ colour/io/luts/tests/test_lut.py:521: note: Consider annotating the ** argument as "**kwargs: Any" or using a TypedDict
+ colour/examples/contrast/examples_contrast.py:104: note: Consider annotating the ** argument as "**kwargs: Any" or using a TypedDict

hydra-zen (https://github.com/mit-ll-responsible-ai/hydra-zen)
+ src/hydra_zen/wrapper/_implementations.py:446: note: Consider annotating the ** argument as "**kwargs: Any" or using a TypedDict

discord.py (https://github.com/Rapptz/discord.py)
+ discord/http.py:806: note: Consider annotating the ** argument as "**kwargs: Any" or using a TypedDict
+ discord/client.py:727: note: Consider annotating the ** argument as "**kwargs: Any" or using a TypedDict
+ discord/ext/commands/context.py:1141: note: Consider annotating the ** argument as "**kwargs: Any" or using a TypedDict

artigraph (https://github.com/artigraph/artigraph)
+ tests/arti/types/test_types.py:146: note: Consider annotating the ** argument as "**kwargs: Any" or using a TypedDict
+ tests/arti/types/test_types.py:150: note: Consider annotating the ** argument as "**kwargs: Any" or using a TypedDict

scipy (https://github.com/scipy/scipy)
+ scipy/fftpack/tests/gen_fftw_ref.py:43: note: Consider annotating the ** argument as "**kwargs: Any" or using a TypedDict
+ scipy/fftpack/tests/gen_fftw_ref.py:59: note: Consider annotating the ** argument as "**kwargs: Any" or using a TypedDict
+ scipy/fftpack/tests/gen_fftw_ref.py:74: note: Consider annotating the ** argument as "**kwargs: Any" or using a TypedDict

pyppeteer (https://github.com/pyppeteer/pyppeteer)
+ pyppeteer/launcher.py:149: note: Consider annotating the ** argument as "**kwargs: Any" or using a TypedDict

jax (https://github.com/google/jax)
+ jax/_src/xla_bridge.py:190: note: Consider annotating the ** argument as "**kwargs: Any" or using a TypedDict
+ jax/_src/pallas/helpers.py:295: note: Consider annotating the ** argument as "**kwargs: Any" or using a TypedDict
+ jax/_src/pallas/helpers.py:297: note: Consider annotating the ** argument as "**kwargs: Any" or using a TypedDict
+ jax/_src/lax/pallas_lowerings/gpu/ragged_dot.py:273: note: Consider annotating the ** argument as "**kwargs: Any" or using a TypedDict
+ jax/_src/lax/pallas_lowerings/gpu/ragged_dot.py:399: note: Consider annotating the ** argument as "**kwargs: Any" or using a TypedDict
+ jax/_src/pallas/einshape.py:330: note: Consider annotating the ** argument as "**kwargs: Any" or using a TypedDict
+ jax/_src/pallas/einshape.py:368: note: Consider annotating the ** argument as "**kwargs: Any" or using a TypedDict

ibis (https://github.com/ibis-project/ibis)
+ ibis/expr/types/temporal.py:1086: note: Consider annotating the ** argument as "**kwargs: Any" or using a TypedDict

apprise (https://github.com/caronc/apprise)
+ apprise/plugins/xmpp/base.py:422: note: Consider annotating the ** argument as "**kwargs: Any" or using a TypedDict
+ apprise/plugins/xmpp/base.py:425: note: Consider annotating the ** argument as "**kwargs: Any" or using a TypedDict

@yosofbadr yosofbadr marked this pull request as ready for review April 15, 2026 20:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Generate better error message for incompatible **kwargs

1 participant