diff --git a/crates/ty_python_semantic/resources/mdtest/scopes/global.md b/crates/ty_python_semantic/resources/mdtest/scopes/global.md index 64b65095fe..cf03d28680 100644 --- a/crates/ty_python_semantic/resources/mdtest/scopes/global.md +++ b/crates/ty_python_semantic/resources/mdtest/scopes/global.md @@ -71,6 +71,19 @@ def f(): reveal_type(x) # revealed: Literal[1] ``` +Same for an `if` statement: + +```py +x: int | None + +def f(): + # The `global` keyword isn't necessary here, but this is testing that it doesn't get in the way + # of narrowing. + global x + if x == 1: + y: int = x # allowed, because x cannot be None in this branch +``` + ## `nonlocal` and `global` A binding cannot be both `nonlocal` and `global`. This should emit a semantic syntax error. CPython diff --git a/crates/ty_python_semantic/src/types/infer.rs b/crates/ty_python_semantic/src/types/infer.rs index 0e00b9eecb..25bb5f8f5a 100644 --- a/crates/ty_python_semantic/src/types/infer.rs +++ b/crates/ty_python_semantic/src/types/infer.rs @@ -6377,7 +6377,13 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> { if let Some(name) = expr.as_name() { if let Some(symbol_id) = place_table.place_id_by_name(name) { if self.skip_non_global_scopes(file_scope_id, symbol_id) { - return global_symbol(self.db(), self.file(), name); + return global_symbol(self.db(), self.file(), name).map_type(|ty| { + self.narrow_place_with_applicable_constraints( + expr, + ty, + &constraint_keys, + ) + }); } is_nonlocal_binding = self .index