Skip to content

Commit a1d98b9

Browse files
asukaminato0721meta-codesync[bot]
authored andcommitted
fix Narrow the type of a when branching on a in b #2608 (#2627)
Summary: Fixes #2608 Implemented narrowing for a in mapping by intersecting the LHS with the mapping key type. This fixes not in branches by negation. Pull Request resolved: #2627 Test Plan: add test Reviewed By: rchen152 Differential Revision: D95416263 Pulled By: yangdanny97 fbshipit-source-id: d016249a6eb9075ed5593d78e9f63607e1f8aba3
1 parent 5a24e5d commit a1d98b9

File tree

2 files changed

+25
-1
lines changed

2 files changed

+25
-1
lines changed

pyrefly/lib/alt/narrow.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -901,7 +901,15 @@ impl<'a, Ans: LookupAnswer> AnswersSolver<'a, Ans> {
901901
return self.intersect(ty, &self.unions(key_types));
902902
}
903903

904-
ty.clone()
904+
// Check if the right operand is a mapping (e.g. dict[str, int]).
905+
// If so, we can narrow the left operand to the mapping's key type.
906+
if !self.behaves_like_any(&right_ty)
907+
&& let Some((key_ty, _)) = self.unwrap_mapping(&right_ty)
908+
{
909+
self.intersect(ty, &key_ty)
910+
} else {
911+
ty.clone()
912+
}
905913
}
906914
AtomicNarrowOp::NotIn(v) => {
907915
// First, check for List, Tuple, and Set literal expressions (syntactic check,

pyrefly/lib/test/narrow.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1662,6 +1662,22 @@ class MyTest(TestCase):
16621662
"#,
16631663
);
16641664

1665+
testcase!(
1666+
test_in_mapping_narrows_key,
1667+
r#"
1668+
from typing import assert_type
1669+
1670+
def parse_resource_id() -> tuple[str, str] | tuple[None, None]: ...
1671+
1672+
def lookup_resource(registry: dict[str, str]) -> str | None:
1673+
kind, _obj_id = parse_resource_id()
1674+
if kind not in registry:
1675+
return None
1676+
assert_type(kind, str)
1677+
return registry[kind]
1678+
"#,
1679+
);
1680+
16651681
// Make sure we catch illegal arguments to isinstance and issubclass even when we aren't narrowing.
16661682
testcase!(
16671683
test_validate_class_object_no_narrow,

0 commit comments

Comments
 (0)