-
Notifications
You must be signed in to change notification settings - Fork 216
Description
Summary
Typeshed includes a __getattr__ method on its stub for types.ModuleType. This makes code like this easier to write: although it is true that not all modules have an __all__ attribute, I do happen to know in this case that all the submodules of typeshed_stats do have __all__ attributes, and it would be somewhat annoying to have to type: ignore these lines. There's no other way of annotating this code to make the type checker happy, and it's pretty often the case that when you're handling a list of ModuleType instances in this way in Python, you know where they came from. A little bit of dynamic typing here goes a long way to improve ergonomics.
Ty ignores ModuleType.__getattr__ when resolving attribute accesses on module literal types, which is good, because otherwise it would consider every module to have every attribute. But it also ignores ModuleType.__getattr__ when resolving attribute accesses on non-literal instances of ModuleType, which doesn't seem right. Ty therefore emits an unresolved-attribute diagnostic on this snippet even though mypy, pyright and pyrefly all have no complaints about it:
import types
def f(x: types.ModuleType):
print(x.__all__)I spotted this by studying the ecosystem report in astral-sh/ruff#20723 (comment)
Version
No response