kwargs.update should allow arguments of different types
This is a pretty weird and possibly obscure bug. If you have a function that has an incorrect return type and you pass its return value to kwargs.update in a function that takes **kwargs, pytype will flag wrong-arg-types in dict.update. Here is a minimal working example:
def mistyped_func() -> None: # Error in the return type
return "Not none!"
def f(**kwargs):
kwargs.update(cat=mistyped_func(), dog="dog")
When I run pytype on this file, I get:
$ pytype --version
2019.10.17
$ python --version
Python 3.7.4
$ pytype demo_func.py
Computing dependencies
Analyzing 1 sources with 0 local dependencies
ninja: Entering directory `/tmp/pytype_demo/.pytype'
[1/1] check demo_func
FAILED: /tmp/pytype_demo/.pytype/pyi/demo_func.pyi
pytype-single --imports_info /tmp/pytype_demo/.pytype/imports/demo_func.imports --module-name demo_func -V 3.7 -o /tmp/pytype_demo/.pytype/pyi/demo_func.pyi --analyze-annotated --nofail --quick /tmp/pytype_demo/demo_func.py
File "/tmp/pytype_demo/demo_func.py", line 2, in mistyped_func: bad option in return type [bad-return-type]
Expected: None
Actually returned: str
File "/tmp/pytype_demo/demo_func.py", line 5, in f: Function dict.update was called with the wrong arguments [wrong-arg-types]
Expected: (self, cat, dog: None, ...)
Actually passed: (self, cat, dog: str)
For more details, see https://google.github.io/pytype/errors.html.
ninja: build stopped: subcommand failed.
It is very strange that for kwargs specifically (this is not triggered by updating a random dictionary) it is inferring this signature, since dict.update should have a signature that accepts any value. I will also note that it's clearly induced by mistyped_func(), but the result of mistyped_func() is being passed to cat rather than dog (this is probably something to do with the way dict.update can take either a single positional dictionary or keyword argument pairs).
The ordering there may be random or semi-random, since it doesn't seem consistent if I add more arguments to update.
Huh. I think the fact the mistyped function and the kwargs error are unrelated, actually. If I run pytype on this code:
def f(**kwargs):
kwargs.update(cat=None, dog="dog")
it still reports:
File "foo.py", line 2, in f: Function dict.update was called with the wrong arguments [wrong-arg-types]
Expected: (self, cat, dog: None, ...)
Actually passed: (self, cat, dog: str)
Seems we expect all the arguments to kwargs.update(...) to have the same type, which is obviously wrong.
How's the fix going?
Unfortunately, we haven't had time to work on this yet.