Improve annotated support with non types - #9625
Conversation
| args = [expr.index] | ||
| base.args = tuple(expr_to_unanalyzed_type(arg, expr) for arg in args) | ||
| if base.name == 'Annotated': | ||
| base.args = (expr_to_unanalyzed_type(args[0], expr), args[1]) |
There was a problem hiding this comment.
this seems to work, but it will probably fail the type checking since now the args are of different types.
There was a problem hiding this comment.
it feels a bit hacky, let me know what you think!
There was a problem hiding this comment.
the check is potentially wrong too, but I think it might be worth checking this PR and maybe try to find a better way to do this 😊
There was a problem hiding this comment.
You're correct that you're failing type checking. You can probably fix the first type error by narrowing / guarding expr.base to the type that it is when its typing.Annotated (probably isinstance(expr.base, RefExpr)?)
The second type error is trickier and might indicate a fundamental problem. If there isn't a way around this, we could band aid this problem by just returning expr_to_unanalyzed_type(args[0], expr). I'd imagine the implication of this is that mypy and mypy plugins won't recognise the alias as being Annotated, but at least we no longer have the false positive.
Finally, Annotated is variadic, so it can have arbitrarily many parameters, so you don't want to just hardcode it to two.
There was a problem hiding this comment.
You're correct that you're failing type checking. You can probably fix the first type error by narrowing / guarding expr.base to the type that it is when its typing.Annotated (probably isinstance(expr.base, RefExpr)?)
Done :)
The second type error is trickier and might indicate a fundamental problem. If there isn't a way around this, we could band aid this problem by just returning expr_to_unanalyzed_type(args[0], expr). I'd imagine the implication of this is that mypy and mypy plugins won't recognise the alias as being Annotated, but that's not a regression and we no longer have the false positive.
I followed your suggestion for now, mostly to see if there's any other failing test.
I wonder if need the annotations anywhere else (I guess it might useful for plugins 🤔)
Happy to change it to something else, but I'm not sure what can we change now (I'm still unfamiliar with mypy's source code) :)
| args = [expr.index] | ||
| base.args = tuple(expr_to_unanalyzed_type(arg, expr) for arg in args) | ||
| if base.name == 'Annotated': | ||
| base.args = (expr_to_unanalyzed_type(args[0], expr), args[1]) |
There was a problem hiding this comment.
You're correct that you're failing type checking. You can probably fix the first type error by narrowing / guarding expr.base to the type that it is when its typing.Annotated (probably isinstance(expr.base, RefExpr)?)
The second type error is trickier and might indicate a fundamental problem. If there isn't a way around this, we could band aid this problem by just returning expr_to_unanalyzed_type(args[0], expr). I'd imagine the implication of this is that mypy and mypy plugins won't recognise the alias as being Annotated, but at least we no longer have the false positive.
Finally, Annotated is variadic, so it can have arbitrarily many parameters, so you don't want to just hardcode it to two.
hauntsaninja
left a comment
There was a problem hiding this comment.
Thanks! I'm okay with this, but I'll leave it for a bit to see if someone else has something to say (I don't really know much about plugins)
|
Looks good. Thanks for the PR! |
Closes #9315
This PR aims to support Annotated to create type Aliases when passing a non type as annotation, like this:
You can test with: