-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[red-knot] Improve type inference for except handlers where a tuple of exception classes is caught #13646
Conversation
// TODO: these `__class_getitem__` diagnostics are all false positives: | ||
// (`builtins.type` is unique at runtime | ||
// as it can be subscripted even though it has no `__class_getitem__` method) | ||
"Cannot subscript object of type `Literal[type]` with no `__class_getitem__` method", | ||
"Cannot subscript object of type `Literal[type]` with no `__class_getitem__` method", | ||
"Cannot subscript object of type `Literal[type]` with no `__class_getitem__` method", | ||
"Cannot subscript object of type `Literal[type]` with no `__class_getitem__` method", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cc. @charliermarsh -- this is a little edge case in the logic you added in #13579. I think the special-casing that allows e.g. type[int]
at runtime is buried deep in the interpreter somewhere. According to all the normal rules, it shouldn't be subscriptable... but it is!
Python 3.12.4 (main, Jun 12 2024, 09:54:41) [Clang 15.0.0 (clang-1500.3.9.4)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> type[int]
type[int]
>>> type.__getitem__
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: type object 'type' has no attribute '__getitem__'. Did you mean: '__getstate__'?
>>> type.__class_getitem__
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: type object 'type' has no attribute '__class_getitem__'
>>> type.__dict__.keys()
dict_keys(['__new__', '__repr__', '__call__', '__getattribute__', '__setattr__', '__delattr__', '__init__', '__or__', '__ror__', 'mro', '__subclasses__', '__prepare__', '__instancecheck__', '__subclasscheck__', '__dir__', '__sizeof__', '__basicsize__', '__itemsize__', '__flags__', '__weakrefoffset__', '__base__', '__dictoffset__', '__name__', '__qualname__', '__bases__', '__mro__', '__module__', '__abstractmethods__', '__dict__', '__doc__', '__text_signature__', '__annotations__', '__type_params__'])
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah this is literally hardcoded directly into PyObject_GetItem
as a special case 🫣
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🙃
I'm working on a PR now to add the special case to our semantic model...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
Summary
There's still a bunch of stuff that is valid in an exception handler but that we can't do type inference for until we have generalised support for
type[T]
. But this improves our type inference for some common cases involving exception tuples. It seems like a nice little short-term winTest plan
I fixed the TODO in the existing test
except_handler_multiple_exceptions
, and added a new test with some new TODOs to illustrate where our type inference still falls short.