diff --git a/crates/ty_python_semantic/resources/mdtest/attributes.md b/crates/ty_python_semantic/resources/mdtest/attributes.md index e04c00f729..98ce6b5aa9 100644 --- a/crates/ty_python_semantic/resources/mdtest/attributes.md +++ b/crates/ty_python_semantic/resources/mdtest/attributes.md @@ -1698,6 +1698,36 @@ reveal_type(outer.nested.inner.Outer.Nested.Inner.attr) # revealed: int outer.nested.inner.Outer.Nested.Inner.attr = "a" ``` +### Unions of module attributes + +`mod1.py`: + +```py +global_symbol: str = "a" +``` + +`mod2.py`: + +```py +global_symbol: str = "a" +``` + +```py +import mod1 +import mod2 + +def _(flag: bool): + if flag: + mod = mod1 + else: + mod = mod2 + + mod.global_symbol = "b" + + # error: [invalid-assignment] "Object of type `Literal[1]` is not assignable to attribute `global_symbol` on type ` | `" + mod.global_symbol = 1 +``` + ## Literal types ### Function-literal attributes diff --git a/crates/ty_python_semantic/src/types/infer.rs b/crates/ty_python_semantic/src/types/infer.rs index 9f3f489745..614bfbb540 100644 --- a/crates/ty_python_semantic/src/types/infer.rs +++ b/crates/ty_python_semantic/src/types/infer.rs @@ -3406,24 +3406,31 @@ impl<'db> TypeInferenceBuilder<'db> { Type::ModuleLiteral(module) => { if let Symbol::Type(attr_ty, _) = module.static_member(db, attribute) { let assignable = value_ty.is_assignable_to(db, attr_ty); - if !assignable { - report_invalid_attribute_assignment( - &self.context, - target.into(), - attr_ty, - value_ty, - attribute, - ); + if assignable { + true + } else { + if emit_diagnostics { + report_invalid_attribute_assignment( + &self.context, + target.into(), + attr_ty, + value_ty, + attribute, + ); + } + false } - - false } else { - if let Some(builder) = self.context.report_lint(&UNRESOLVED_ATTRIBUTE, target) { - builder.into_diagnostic(format_args!( - "Unresolved attribute `{}` on type `{}`.", - attribute, - object_ty.display(db) - )); + if emit_diagnostics { + if let Some(builder) = + self.context.report_lint(&UNRESOLVED_ATTRIBUTE, target) + { + builder.into_diagnostic(format_args!( + "Unresolved attribute `{}` on type `{}`.", + attribute, + object_ty.display(db) + )); + } } false