-
Notifications
You must be signed in to change notification settings - Fork 216
Description
Our reasons why we currently union with Unknown are described in https://github.com/astral-sh/ruff/blob/main/crates/ty_python_semantic/resources/mdtest/doc/public_type_undeclared_symbols.md
While this is technically reasonable, from a gradual guarantee perspective, and consistent with our class-attribute behavior, I think ultimately for module globals, it's the wrong tradeoff for users.
External mutation of module globals is relatively rare, and I don't think it is important that we avoid "false positives" on code that does that. It is fine if you need to add a wider annotation to your module global in this uncommon case, so as to explicitly allow an external mutation you want to be able to do.
On the flip side, un-annotated module globals with unambiguous types that aren't intended for external mutation are common, and requiring them to be annotated or Final in order to avoid the union with Unknown is just irritating and doesn't add value.
I think the tradeoffs are different for class attributes, where mutation (if you include mutation on instances) is very common. That's not to say we won't ultimately decide to change course there, as well, but I think initially it makes sense to just change this for module globals.
This would also imply no longer unioning with Unknown when unannotated module globals are referenced from a nested scope in the same module.