Skip to content

[ty] Use the top materialization of classes for narrowing in class-patterns for match statements#21150

Merged
AlexWaygood merged 2 commits intomainfrom
alex/match-top-materialization
Oct 30, 2025
Merged

[ty] Use the top materialization of classes for narrowing in class-patterns for match statements#21150
AlexWaygood merged 2 commits intomainfrom
alex/match-top-materialization

Conversation

@AlexWaygood
Copy link
Member

@AlexWaygood AlexWaygood added bug Something isn't working ty Multi-file analysis & type inference labels Oct 30, 2025
@github-actions
Copy link
Contributor

github-actions bot commented Oct 30, 2025

Diagnostic diff on typing conformance tests

No changes detected when running ty on typing conformance tests ✅

@github-actions
Copy link
Contributor

github-actions bot commented Oct 30, 2025

mypy_primer results

Changes were detected when running on open source projects
Expression (https://github.com/cognitedata/Expression)
- expression/core/result.py:85:73: error[invalid-return-type] Function can implicitly return `None`, which is not assignable to return type `_TSource@default_with | _TSourceOut@Result`
- expression/core/result.py:97:65: error[invalid-return-type] Function can implicitly return `None`, which is not assignable to return type `Result[_TResult@map, _TErrorOut@Result]`
- expression/core/result.py:113:10: error[invalid-return-type] Function can implicitly return `None`, which is not assignable to return type `Result[_TResult@map2, _TErrorOut@Result]`
- expression/core/result.py:125:70: error[invalid-return-type] Function can implicitly return `None`, which is not assignable to return type `Result[_TSourceOut@Result, _TResult@map_error]`
- expression/core/result.py:137:86: error[invalid-return-type] Function can implicitly return `None`, which is not assignable to return type `Result[_TResult@bind, _TErrorOut@Result]`
- expression/core/result.py:177:10: error[invalid-return-type] Function can implicitly return `None`, which is not assignable to return type `Result[_TSourceOut@Result, _TErrorOut@Result]`
- expression/core/result.py:191:23: error[invalid-return-type] Function can implicitly return `None`, which is not assignable to return type `dict[str, _TSourceOut@Result | _TErrorOut@Result | Literal["ok", "error"]]`
- expression/core/result.py:205:23: error[invalid-return-type] Function can implicitly return `None`, which is not assignable to return type `Result[_TErrorOut@Result, _TSourceOut@Result]`
- expression/core/result.py:269:26: error[invalid-return-type] Function can implicitly return `None`, which is not assignable to return type `str`
- expression/core/try_.py:24:26: error[invalid-return-type] Function can implicitly return `None`, which is not assignable to return type `str`
- expression/effect/async_result.py:32:10: error[invalid-return-type] Function can implicitly return `None`, which is not assignable to return type `Result[_TResult@bind, _TError@AsyncResultBuilder]`
- expression/effect/async_result.py:79:94: error[invalid-return-type] Function can implicitly return `None`, which is not assignable to return type `Result[_TSource@AsyncResultBuilder, _TError@AsyncResultBuilder]`
- Found 213 diagnostics
+ Found 201 diagnostics
No memory usage changes detected ✅

@MeGaGiGaGon
Copy link
Contributor

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 :)

@AlexWaygood AlexWaygood reopened this Oct 30, 2025
@AlexWaygood AlexWaygood enabled auto-merge (squash) October 30, 2025 20:37
@AlexWaygood AlexWaygood merged commit 13375d0 into main Oct 30, 2025
51 of 78 checks passed
@AlexWaygood AlexWaygood deleted the alex/match-top-materialization branch October 30, 2025 20:44
dcreager added a commit that referenced this pull request Oct 31, 2025
* 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)
Comment on lines +128 to +144
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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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()

Copy link
Member Author

@AlexWaygood AlexWaygood Jan 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I opened #23011 to remove this special case. Can you take a look?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working ty Multi-file analysis & type inference

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Class pattern matching fails for final non-bivariant classes

4 participants