Skip to content

Commit dbc5c06

Browse files
kinto0meta-codesync[bot]
authored andcommitted
Fix false unknown-name error for Literal imported via try/except
Summary: When `Literal` is imported via a `try/except` block (e.g. `from typing import Literal` in try, `from typing_extensions import Literal` in except), the flow merge produces `FlowStyle::Other` because the two imports come from different modules. This caused `as_special_export()` to fail to recognize `Literal` as a special form, so strings inside `Literal["test"]` were treated as forward references, producing spurious `unknown-name` errors. The fix adds handling for `Binding::Import` and `Binding::Phi` in `special_export_from_binding_idx`. For Phi nodes (merged try/except branches), all branches are checked recursively and the result is returned if they agree on the same `SpecialExport`. fixes #2407 Reviewed By: stroxler Differential Revision: D93287592 fbshipit-source-id: 86ccc87f40155860870a2132a6a41cd9d8a550d0
1 parent 4fb7136 commit dbc5c06

File tree

2 files changed

+40
-0
lines changed

2 files changed

+40
-0
lines changed

pyrefly/lib/binding/bindings.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -983,6 +983,28 @@ impl<'a> BindingsBuilder<'a> {
983983
Binding::NameAssign { expr: value, .. } => {
984984
return self.as_special_export_inner(value, visited_names, visited_keys);
985985
}
986+
Binding::Import(module_name, name, _) => {
987+
return self.lookup.is_special_export(*module_name, name);
988+
}
989+
Binding::Phi(_, branches) => {
990+
// Check all branches for a consistent special export (e.g. try/except
991+
// importing Literal from typing vs typing_extensions).
992+
let mut result = None;
993+
for branch in branches {
994+
let branch_result = self.special_export_from_binding_idx(
995+
branch.value_key,
996+
visited_names,
997+
visited_keys,
998+
);
999+
match (&result, &branch_result) {
1000+
(None, _) => result = branch_result,
1001+
(_, None) => {}
1002+
(Some(a), Some(b)) if a == b => {}
1003+
_ => return None,
1004+
}
1005+
}
1006+
return result;
1007+
}
9861008
_ => return None,
9871009
}
9881010
}

pyrefly/lib/test/literal.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,3 +403,21 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor i
403403
assert_type(x, LiteralString)
404404
"#,
405405
);
406+
407+
testcase!(
408+
test_literal_try_except_import,
409+
r#"
410+
from typing import assert_type
411+
412+
try:
413+
from typing import Literal
414+
except ImportError:
415+
from typing_extensions import Literal
416+
417+
def fun(param: Literal["test"] = "test"):
418+
assert_type(param, Literal["test"])
419+
420+
x: Literal["a", "b"] = "a"
421+
assert_type(x, Literal["a", "b"])
422+
"#,
423+
);

0 commit comments

Comments
 (0)