Skip to content

Commit e567467

Browse files
yangdanny97meta-codesync[bot]
authored andcommitted
Fix false positive error on isinstance with type | T
Summary: When `isinstance(x, type | int)` was used, pyrefly incorrectly reported an error because the `type` metatype gets canonicalized to `Type::Type(Any)` inside the union. The `as_class_info` function then double-wrapped it with `mk_type_form`, producing `Type::Type(Type::Type(Any))` which `unwrap_class_object_silently` could not handle. Fix: in `as_class_info`, skip wrapping union members that are already `Type::Type(...)` to avoid double-wrapping. fixes #2871 Reviewed By: rchen152 Differential Revision: D98300571 fbshipit-source-id: ae264bdd9a5518baa62cb754ea1646e587b6ab4b
1 parent a2aed80 commit e567467

2 files changed

Lines changed: 24 additions & 0 deletions

File tree

pyrefly/lib/alt/class/classdef.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,11 @@ impl<'a, Ans: LookupAnswer> AnswersSolver<'a, Ans> {
150150
}
151151
Type::Type(box Type::Tuple(_)) => Some(self.instantiate_unbounded_tuple()),
152152
Type::Type(box Type::Any(a)) => Some((TParams::empty(), a.propagate())),
153+
// type[type[Any]] is what we get when `type` appears in an annotation position.
154+
// We treat it as type[Any].
155+
Type::Type(box ty @ Type::Type(box Type::Any(_))) => {
156+
Some((TParams::empty(), ty.clone()))
157+
}
153158
Type::Type(box Type::SpecialForm(SpecialForm::Callable)) => Some((
154159
TParams::empty(),
155160
self.heap

pyrefly/lib/test/narrow.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -727,6 +727,25 @@ def f(x: str | int | None):
727727
"#,
728728
);
729729

730+
testcase!(
731+
test_isinstance_union_with_type,
732+
r#"
733+
from typing import assert_type
734+
def f(x: object):
735+
if isinstance(x, type | int):
736+
assert_type(x, type | int)
737+
isinstance(x, type | int)
738+
"#,
739+
);
740+
741+
testcase!(
742+
test_issubclass_union_with_type,
743+
r#"
744+
def f(cls: type):
745+
issubclass(cls, type | int)
746+
"#,
747+
);
748+
730749
testcase!(
731750
test_isinstance_of_tuple,
732751
r#"

0 commit comments

Comments
 (0)