fix assert_type with metaclasses #3228#3243
fix assert_type with metaclasses #3228#3243asukaminato0721 wants to merge 1 commit intofacebook:mainfrom
Conversation
|
According to mypy_primer, this change doesn't affect type check results on a corpus of open source code. ✅ |
There was a problem hiding this comment.
Pull request overview
Fixes typing.assert_type behavior for classes with custom metaclasses so that asserting a class object against its metaclass (e.g., assert_type(A, Meta)) correctly fails, aligning with the typing spec and other type checkers.
Changes:
- Updated
call_assert_typeto explicitly treat “class object is an instance of a non-typemetaclass” as a mismatch forassert_typeequivalence. - Added a regression test covering
assert_typewith a custom metaclass.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| pyrefly/lib/test/simple.rs | Adds a regression testcase ensuring assert_type(A, Meta) produces an error for metaclass instances. |
| pyrefly/lib/alt/special_calls.rs | Adjusts assert_type checking logic to reject metaclass-instance matches (except for builtin type) even if prior equivalence logic allowed them. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| let matches_metaclass_instance = match (&a, &b) { | ||
| (Type::ClassDef(got), Type::ClassType(want)) => { | ||
| !want.is_builtin("type") && self.type_order().has_metaclass(got, want) | ||
| } | ||
| (Type::Type(box Type::ClassType(got)), Type::ClassType(want)) => { | ||
| !want.is_builtin("type") | ||
| && self.type_order().has_metaclass(got.class_object(), want) | ||
| } | ||
| _ => false, | ||
| }; | ||
| if matches_metaclass_instance || !self.is_equivalent(&a, &b) { |
There was a problem hiding this comment.
matches_metaclass_instance is a boolean that triggers the error path when true, so the name reads as if it's a success condition even though it represents a mismatch case. Consider renaming it (e.g., is_metaclass_assert_mismatch / metaclass_instance_mismatch) or inverting the boolean so the if condition reads more directly.
Summary
Fixes #3228
assert_type no longer accepts a class object as exactly equal to its non-type metaclass.
Test Plan
add test