[ty] Use the top materialization of classes for narrowing in class-patterns for match statements#21150
Conversation
…tterns for `match` statements
Diagnostic diff on typing conformance testsNo changes detected when running ty on typing conformance tests ✅ |
|
|
That's fun in the primer seeing a bunch of Expression Result diagnostics going away, since my issue came from also running into this making my own Result type :) |
* origin/main: [ty] Fix generic inference for non-dataclass inheriting from generic dataclass (#21159) Update etcetera to 0.11.0 (#21160) Fix missing diagnostics for notebooks (#21156) [ty] Fix tests for definition completions (#21153) Bump v0.14.3 (#21152) [ty] Don't provide completions when in class or function definition (#21146) [ty] Use the top materialization of classes for narrowing in class-patterns for `match` statements (#21150)
| from typing import Any | ||
|
|
||
| X = Any | ||
|
|
||
| def f(obj: object): | ||
| match obj: | ||
| case int(): | ||
| reveal_type(obj) # revealed: int | ||
| case X(): | ||
| reveal_type(obj) # revealed: Any & ~int | ||
|
|
||
| def g(obj: object, Y: Any): | ||
| match obj: | ||
| case int(): | ||
| reveal_type(obj) # revealed: int | ||
| case Y(): | ||
| reveal_type(obj) # revealed: Any & ~int |
There was a problem hiding this comment.
Alex, I did not understand this test case. The first test with X() gives a runtime error if the Any() match arm is checked. And in the real-code example you linked, I don't think any match arm is checking for Any()?
[nav] In [1]: from typing import Any
...:
...: X = Any
...:
...: def f(obj: object):
...: match obj:
...: case int():
...: ...
...: case X():
...: ...
[ins] In [2]: f("")
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[2], line 1
----> 1 f("")
Cell In[1], line 9, in f(obj)
7 case int():
8 ...
----> 9 case X():
10 ...
File ~/.local/share/uv/python/cpython-3.11.13-macos-aarch64-none/lib/python3.11/typing.py:515, in _AnyMeta.__instancecheck__(self, obj)
513 def __instancecheck__(self, obj):
514 if self is Any:
--> 515 raise TypeError("typing.Any cannot be used with isinstance()")
516 return super().__instancecheck__(obj)
TypeError: typing.Any cannot be used with isinstance()There was a problem hiding this comment.
I think I did this because it fixed a bunch of unexpected ecosystem diagnostics on one project that had this pattern, which showed up in an early version of this PR. But it's possible that I reacted too rashly to the unexpected diagnostics; maybe we just shouldn't support that pattern. I'm open to changing this!
There was a problem hiding this comment.
I opened #23011 to remove this special case. Can you take a look?
Fixes astral-sh/ty#1458