Originally posted by @AlexWaygood in #106354 (comment):
Tools/clinic/clinic.py:5039: error: Incompatible return value type (got
"tuple[str, bool, dict[str | None, Any]]", expected
"tuple[str, bool, dict[str, Any]]") [return-value]
return name, False, kwargs
^~~~~~~~~~~~~~~~~~~
I think mypy is flagging a real bug in the code here. The issue is this block of code here:
|
case ast.Call(func=ast.Name(name)): |
|
symbols = globals() |
|
kwargs = { |
|
node.arg: eval_ast_expr(node.value, symbols) |
|
for node in annotation.keywords |
|
} |
|
return name, False, kwargs |
The function is annotated as return tuple[str, bool, KwargDict], and KwargDict is a type alias for dict[str, Any]. It's important that the dictionary that's the third element of the tuple only has strings as keys. If it doesn't, then this will fail:
|
return_converter = return_converters[name](**kwargs) |
The code as written, however, doesn't guarantee that all the keys in the kwargs dictionary will be strings. In the dictionary comprehension, we can see that annotation is an ast.Call instance. That means that annotation.keywords is of type list[ast.keyword] -- we can see this from typeshed's stubs for the ast module (which are an invaluable reference if you're working with ASTs in Python!): https://github.com/python/typeshed/blob/18d45d62aabe68fce78965c4920cbdeddb4b54db/stdlib/_ast.pyi#L324-L329. If annotation.keywords is of type list[ast.keyword], that means that the node variable in the dictionary comprehension is of type keyword, which means (again using typeshed's ast stubs), that node.arg is of type str | None: https://github.com/python/typeshed/blob/18d45d62aabe68fce78965c4920cbdeddb4b54db/stdlib/_ast.pyi#L516-L520. AKA, the keys in this dictionary are not always guaranteed to be strings -- there's a latent bug in this code!
Linked PRs
Originally posted by @AlexWaygood in #106354 (comment):
I think mypy is flagging a real bug in the code here. The issue is this block of code here:
cpython/Tools/clinic/clinic.py
Lines 5033 to 5039 in d694f04
The function is annotated as return
tuple[str, bool, KwargDict], andKwargDictis a type alias fordict[str, Any]. It's important that the dictionary that's the third element of the tuple only has strings as keys. If it doesn't, then this will fail:cpython/Tools/clinic/clinic.py
Line 4617 in d694f04
The code as written, however, doesn't guarantee that all the keys in the
kwargsdictionary will be strings. In the dictionary comprehension, we can see thatannotationis anast.Callinstance. That means thatannotation.keywordsis of typelist[ast.keyword]-- we can see this from typeshed's stubs for theastmodule (which are an invaluable reference if you're working with ASTs in Python!): https://github.com/python/typeshed/blob/18d45d62aabe68fce78965c4920cbdeddb4b54db/stdlib/_ast.pyi#L324-L329. Ifannotation.keywordsis of typelist[ast.keyword], that means that thenodevariable in the dictionary comprehension is of typekeyword, which means (again using typeshed'saststubs), thatnode.argis of typestr | None: https://github.com/python/typeshed/blob/18d45d62aabe68fce78965c4920cbdeddb4b54db/stdlib/_ast.pyi#L516-L520. AKA, the keys in this dictionary are not always guaranteed to be strings -- there's a latent bug in this code!Linked PRs